Download Lists

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Array data structure wikipedia , lookup

Lattice model (finance) wikipedia , lookup

Red–black tree wikipedia , lookup

Quadtree wikipedia , lookup

Binary tree wikipedia , lookup

Interval tree wikipedia , lookup

Binary search tree wikipedia , lookup

B-tree wikipedia , lookup

Linked list wikipedia , lookup

Transcript
Lists
Chapter 8
2
Linked Lists
• As an ADT, a list is
– finite sequence (possibly empty) of elements
Operations commonly include:
• Construction
• Empty
• Traverse
• Insert
• Delete
Allocate & initialize object
Check if it is empty
Go through list, process elements in
order stored
Add an item to list at any point
Remove an item from the list at any point
3
Array/Vector Implementation of List
• Data Members:
– Store the list items in consecutive array or
vector locations
a1,
a2,


a[0] a[1]
a3 , . . .

a[2]
...
an

a[n-1], a[n] ... a[CAPACITY-1]
For an array, add a mySize member to store the
length (n) of the list.
4
Array/Vector Implementation of List
Operations
Construction: Set mySize to 0;
if run-time array, allocate memory for it
For vector: let its constructor do the
work
Empty:
mySize == 0
For vector: Use its empty() operation
5
Array/Vector Implementation of List
Traverse:
for (int i = 0; i < size; i++)
{ Process(a[i]); }
or
i = 0;
while (i < size)
{ Process(a[i]); i++; }
6
Array/Vector Implementation of List
• Insert:
Insert 6 after 5 in
3, 5, 8, 9, 10, 12, 13, 15
3, 5, 6, 8, 9, 10, 12, 13, 15
Have to shift array elements to make room.
• Delete
Delete 5 from
3, 5, 6. 8, 9, 10, 12, 13, 15
3, 6, 8, 9, 10, 12, 13, 15
Have to shift array elements to close the gap.
7
Array/Vector Implementation of List
• This implementation of lists is inefficient for
dynamic lists
– Those that change frequently
– Those with many insertions and deletions
So …
We look for an alternative implementation.
8
Linked List
For the array/vector-based implementation:
1. First element is at location 0
2. Successor of item at location i is at location
i + 1
3. End is at location size – 1
Fix:
1. Remove requirement that list elements be
stored in consecutive location.
2. But then need a "link" that connects each
element to its successor
Linked Lists !!
9
Linked Lists
• Definition <=> A linked list of selfreferential class objects
– called nodes
– connected by pointer links (thus, a "linked"
list)
• Subsequent nodes accessed via linkpointer member stored in each member
• Link pointer in last node set to null (zero)
– marks the end of the list
• Nodes created dynamically, as needed
10
Self-Referential Classes
• A self-referential class contains a pointer
member that points to a class object of the
same class type
class Part_node {
public:
Part_node ( );
…
private:
char part_num[8], descrip[20];
int qty; float price;
Part_node *next_part; } ;
11
Self-Referential Classes
• This pointer to an object of the type being
declared enables class objects to be
linked together in various ways
– This is how we get linked lists
0
Pointer
variable
Pointer
Member
Link
Null
Pointer
12
Dynamic Memory Allocation
• If the data structures are to be dynamic,
then dynamic memory allocation is
required
– operators new and delete are essential
part_node *newPtr = new part_node;
0
Creates the
new pointer Allocates the space for
a new part node
13
Dynamic Memory Allocation
• The delete operator deallocates memory
allocated with the new
• Note: newPtr is not itself deleted -- rather
the space newPtr points to
delete newPtr;
0
14
Linked Lists Operations
• Construction: first = null_value;
• Empty:
first == null_value?
• Traverse
ptr = first;
while (ptr != null_value)
{
Process data part of node pointed to by ptr
ptr = next part of node pointed to by ptr;
}
15
first
9
17
22
26
34
9
17
22
26
34
22
26
34
Traverse
ptr
ptr = first;
while (ptr != null_value)
{
Process data part of
node pointed to by ptr;
first
ptr
.
.
.
ptr = next part of node
pointed to by ptr;
}
first
9
17
ptr
first
9
17
22
26
34
ptr
16
Operations: Insertion
predptr
first
• Insertion
–
–
–
–
–
9
newptr
17
22
26
34
20
To insert 20 after 17
Need address of item before point of insertion
predptr points to the node containing 17
Get a new node pointed to by newptr and store 20 in it
Set the next pointer of this new node equal to the next
pointer in its predecessor, thus making it point to its
successor.
– Reset the next pointer of its predecessor to point to this
And voila! The node is inserted
new node
(linked) into the list
17
Operations: Insertion
• Note: insertion also works at end of list
– pointer member of new node set to null
• Insertion at the beginning of the list
– predptr must be set to first
– pointer member of newptr set to that value
– first set to value of newptr
 Note: In all cases, no shifting of list
elements is required !
18
Operations: Deletion
predptr
first
5
9
17
ptr
20
22
29
• Delete node containing 22 from list.
– Suppose ptr points to the node to be deleted
– predptr points to its predecessor (the 20)
• Do a bypass operation:
– Set the next pointer in the predecessor to
point to the successor of the node to be deleted
– Deallocate the node being deleted.
34
To free
space
19
Linked Lists - Advantages
• Access any item as long as external
link to first item maintained
• Insert new item without shifting
• Delete existing item without shifting
• Can expand/contract as necessary
20
Linked Lists - Disadvantages
• Overhead of links:
– used only internally, pure overhead
• If dynamic, must provide
– destructor
– copy constructor
• No longer have direct access to each element of
the list
– Many sorting algorithms need direct access
– Binary search needs direct access
• O(1) access becomes O(n) access
– must go through first element, and then second, and
then third, etc.
21
Linked Lists - Disadvantages
• List-processing algorithms that require fast access to each
element cannot be done as efficiently with linked lists.
• Consider adding an element at the end of the list
Array
a[size++] = value;
or for a vector:
v.push_back(value);
This is the inefficient part
Linked List
Get a new node;
set data part = value
next part = null_value
If list is empty
Set first to point to new node.
Else
Traverse list to find last node
Set next part of last node to
point to new node.
22
Using C++ Pointers and Classes
• To Implement Nodes
class Node
{
public:
DataType data;
Node * next;
};
• Note: The definition of a Node is recursive
– (or self-referential)
• It uses the name Node in its definition
• The next member is defined as a pointer to a
Node
23
Working with Nodes
• Declaring pointers
Node * ptr;
or
typedef Node * NodePointer;
NodePointer ptr;
• Allocate and deallocate
ptr = new Node;
delete ptr;
• Access the data and next part of node
(*ptr).data and
(*ptr).next
or
ptr->data
and
ptr->next
24
Working with Nodes
• Note data members
are public
class Node
{ public:
DataType data;
Node * next;
};
• This class declaration will be placed inside
another class declaration for LinkedList
• The data members data and next of struct
Node will be public inside the class
– will accessible to the member and friend
functions
– will be private outside the class
25
Class Template LinkedList
template <typename DataType>;
class LinkedList
{
private:
class Node
{
public:
DataType data;
Node * next;
};
typedef Node * NodePointer;
...
};
• data is public inside
class Node
• class Node is private
inside LinkedList
26
Data Members for LinkedList
first
9
17
22
26
34
• A linked list will be characterized by:
– A pointer to the first node in the list.
– Each node contains a pointer to the next node in
the list
– The last node contains a null pointer
• As a variation first may
– be a structure
– also contain a count of the elements in the list
27
Function Members for LinkedList
• Constructor
L
– Make first a null pointer and
– set mySize to 0
first
mySize
0
• Destructor
– Nodes are dynamically allocated by new
– Default destructor will not specify the delete
– All the nodes from that point on would be
"marooned memory"
– A destructor must be explicitly implemented to
do the delete
28
Function Members for LinkedList
L
9
first
mySize
22
26
34
5
copyOfL
9
first
mySize
17
17
22
26
34
5
• Copy constructor
– By default, when a copy is made of a
LinkedList object, it only gets the head pointer
– Copy constructor will make a new linked list of
nodes to which copyOfL will point
29
Variations
• An empty head node
– Every node has a predecessor
– Does away with special case insertions
• An empty trailer node
– Every node has a successor
• Doubly linked list
L
prev
last
9
first
mySize
5
next
17
22
26
34
30
The STL list<T> Class Template
• A sequential container
– Optimized for insertion and erasure at
arbitrary points in the sequence.
– Implemented as a circular doubly-linked list
with head node.
L
prev
last
data
first
mySize
5
9
next
17
22
26
34
31
The STL list<T> Class Template
Node structure
struct list_node
{ pointer next,
prev;
T data;
}
32
The STL list<T> Class Template
• But it's allo/deallo-cation scheme is
complex
– Does not simply using new and delete
operations.
• Using the heap manager is inefficient for
large numbers of allo/deallo-cations
– Thus it does it's own memory management.
33
The STL list<T> Memory Management
When a node is allocated
1. If there is a node on the free list, allocate it.
•
This is maintained as a linked stack
2. If the free list is empty:
a) Call the heap manager to allocate a block of
memory (a "buffer", typically 4K)
b) Carve it up into pieces of size required for a
node of a list<T>.
34
The STL list<T> Memory Management
• When a node is deallocated
– Push it onto the free list.
• When all lists of this type T have been
destroyed
– Return it to the heap
35
Comparing List<t> With Other Containers
Property
Array
vector<T> deque<T> list<T>
Direct/random access ([])
+ (exclnt) +
 (good)
X
Sequential access
+
+

+
Insert/delete at front
-(poor)
-
+
+
Insert/delete at end
+
+
+
+
Insert/delete in middle
-
-
-
+
Overhead
lowest
low
low/medium
• Note : list<T> does not support direct
access
– does not have the subscript operator [ ].
high
36
list<t> Iterators
• list<T>'s iterator is "weaker" than that
for vector<T>.
 vector<T>: random access iterators
 list<T>:
bidirectional iterators
• Operations in common
 ++
 -*
Move iterator to next element
(like ptr = ptr-> next)
Move iterator to preceding element
(like ptr = ptr-> prev)
dereferencing operator
(like ptr-> data)
37
list<t> Iterators
• Operators in common
=
assignment
(for same type iterators)
it1 = it2 makes it1 positioned at same
element as it2
 == and !=
(for same type iterators)
checks whether iterators are positioned at the
same element
38
Using list<t> Iterators
Example: Construct a list containing first 4
even integers; then output the list.
list<int> l;
for (int i = 1; i <= 4; i++)
l.push_back(2*i);
for (list<int>::iterator it = l.begin();
it != l.end(); it++)
cout << *it << " ";
cout << endl;
39
Limitations of list<t> Iterators
• Directional iterators don't have:
+, -, +=, -=, []
• list<t> iterators cannot do "jumping"
– No
iterator ± n
– No direct access
• Result, cannot implement some sort()
algorithms
– Solution: list<T> has it's own sort()
operation
40
Basic list<t> Operations
• See page 451,2
–
–
–
–
–
–
Constructors
Destructors
Empty, Size
Push, insert, pop, remove
Front, back
Iterator functions:
• begin, end,
– Sort
– Merge, splice
– Comparisons