Linked List
Linked List
List Definitions
• Linear relationship Each element except the first has a unique predecessor, and each element except the last has a unique successor.
• Length The number of items in a list; the length can vary over time.
Abstract Data Type (ADT)
• A data type whose properties (domain and operations) are specified independently of any particular implementation.
• Logical (or ADT) level: abstract view of the domain and operations.
• Implementation level: specific representation of the structure to hold the data items, and the coding for operations.
4 Basic Kinds of ADT Operations
• Constructor/Destructor – creates/deletes a new instance (object) of an ADT.
• Transformer -- changes the state of one or more of the data values of an instance.
• Observer -- allows us to observe the state of one or more of the data values of an instance without changing them.
• Iterator -- allows us to process all the components in a data
structure sequentially.
ADT List Operations
• Transformers – MakeEmpty( ) – InsertItem ( )– DeleteItem( )
• Observers – LengthIs( )– RetrieveItem( )
• Iterators – ResetList( )– GetNextItem( )
change state
observe state
process all
class List{public :
void UnsortedType ( ) ; int LengthIs ( ) const ; void RetrieveItem (ItemType& item,
bool& found ) ;void InsertItem ( ItemType item ) ; void DeleteItem ( ItemType item );void ResetList ( );void GetNextItem ( ItemType& item );
private :int length ; ItemType info[MAX_ITEMS] ; int currentPos ;
} ;
Class List
use array to
store data
Singly Linked List Diagram
Pointer to front node
A B C NULL
Nodes
Data carried in node Pointer to next node
Node from Shop Program Diagram
A
Item item; Node *link;
class Node {public: Node(Item i);private: Item item; Node *link;};
Empty Insert Example (1 of 6)
size
prev cur pos
0
anItem
A? ?
void ShoppingList::insert(const Item & anItem, int pos) { Node *prev, *cur; Inserting A at position 0 in empty list
front
0
Empty Insert Example (2 of 6)
size
prev cur pos
0
anItem
A? ?
assert(pos >= 0 && pos <= size); size++;
front
1
Empty Insert Example (3 of 6)
size
prev cur pos
0
anItem
A?
if (pos == 0) { // Inserting at the front cur = front;
front
1
Empty Insert Example (4 of 6)
size
prev cur pos
0
anItem
A?
front = new Node(anItem);
front
1
A
item link
?
Empty Insert Example (5 of 6)
size
prev cur pos
0
anItem
A?
front->link = cur;
front
1
A
item link
Empty Insert Example (6 of 6)
size
return; }
front
1
A
item link
Front Insert Example (1 of 6)
front
A B C
item link item link item link
prev cur pos
0
anItem
D? ?
void ShoppingList::insert(const Item & anItem, int pos) { Node *prev, *cur; Inserting D at position 0
size
3
Front Insert Example (2 of 6)
front
A B C
item link item link item link
prev cur pos
0
anItem
D? ?
assert(pos >= 0 && pos <= size); size++;
size
4
Front Insert Example (3 of 6)
front
A B C
item link item link item link
prev cur pos
0
anItem
D?
if (pos == 0) { // Inserting at the front cur = front;
size
4
Front Insert Example (4 of 6)
front
A B C
item link item link item link
prev cur pos
0
anItem
D?
front = new Node(anItem);
size
4
D
item link
?
Front Insert Example (5 of 6)
front
A B C
item link item link item link
prev cur pos
0
anItem
D?
front->link = cur;
size
4
D
item link
Front Insert Example (6 of 6)
front
A B C
item link item link item link
return; }
size
4
D
item link
Middle Insert Example (1 of 8)void ShoppingList::insert(const Item & anItem, int pos) { Node *prev, *cur; Inserting D at position 2
front
A B C
item link item link item link
prev cur pos
2
anItem
D? ?
size
3
Middle Insert Example (2 of 8) assert(pos >= 0 && pos <= size); size++;
front
A B C
item link item link item link
prev cur pos
2
anItem
D? ?
size
4
Middle Insert Example (3 of 8) prev = NULL; cur = front;
front
A B C
item link item link item link
prev cur pos
2
anItem
D
size
4
Middle Insert Example (4 of 8) while (pos > 0) { prev = cur; cur = cur->link; pos--; }
First Iteration
front
A B C
item link item link item link
prev cur pos
1
anItem
D
size
4
Middle Insert Example (5 of 8) while (pos > 0) { prev = cur; cur = cur->link; pos--; }
Second Iteration
front
A B C
item link item link item link
prev cur pos
0
anItem
D
size
4
Middle Insert Example (6 of 8) prev->link = new Node(anItem);
front
A B C
item link item link item link
prev cur pos
0
anItem
D
size
4
D ?
item link
Middle Insert Example (7 of 8) prev->link->link = cur;
front
A B C
item link item link item link
prev cur pos
0
anItem
D
size
4
D
item link
Middle Insert Example (8 of 8)}
front
A B C
item link item link item link
size
4
D
item link
End Insert Example (1 of 8)void ShoppingList::insert(const Item & anItem, int pos) { Node *prev, *cur; Inserting D at position 3
front
A B C
item link item link item link
prev cur pos
3
anItem
D? ?
size
3
End Insert Example (2 of 8) assert(pos >= 0 && pos <= size); size++;
front
A B C
item link item link item link
prev cur pos
3
anItem
D? ?
size
4
End Insert Example (3 of 8) prev = 0; cur = front;
front
A B C
item link item link item link
prev cur pos
3
anItem
D0
size
4
End Insert Example (4 of 8) while (pos > 0) { prev = cur; cur = cur->link; pos--; }
First Iteration
front
A B C
item link item link item link
prev cur pos
2
anItem
D
size
4
End Insert Example (5 of 8) while (pos > 0) { prev = cur; cur = cur->link; pos--; }
Second Iteration
front
A B C
item link item link item link
prev cur pos
1
anItem
D
size
4
End Insert Example (6 of 8) while (pos > 0) { prev = cur; cur = cur->link; pos--; }
Third Iteration
front
A B C
item link item link item link
prev cur pos
0
anItem
D
size
4
End Insert Example (7 of 8) prev->link = new Node(anItem); prev->link->link = cur;
front
A B C
item link item link item link
prev cur pos
0
anItem
D
size
4
D
item link
End Insert Example (8 of 8) }
front
A B C
item link item link item link
size
4
D
item link
Remove Example (1 of 7)void ShoppingList::remove(int pos) { Node *cur, *prev; Removing at position 1
front
A B C
item link item link item link
prev cur pos
1? ?
size
3
Remove Example (2 of 7) assert(pos >= 0 && pos < size); size--;
front
A B C
item link item link item link
prev cur pos
1? ?
size
2
Remove Example (3 of 7) prev = NULL; cur = front;
front
A B C
item link item link item link
prev cur pos
1
size
2
Remove Example (4 of 7) while (pos > 0) { prev = cur; cur = cur->link; pos--; }
front
A B C
item link item link item link
prev cur pos
0
size
2
First iteration
Remove Example (5 of 7) prev->link = cur->link;
front
A B C
item link item link item link
prev cur pos
0
size
2
Remove Example (6 of 7) delete cur;
front
A B C
item link item link item link
prev cur pos
0
size
2
Remove Example (7 of 7)}
front
A C
item link item link
size
2
Delete All Example (1 of 8)void ShoppingList::deleteAll() { Node *kil;
front
A B C
item link item link item link
kil
?
size
3
Delete All Example (2 of 8) while (front != NULL) { kil = front; front = front->link;
A B C
item link item link item link
kil
frontsize
3
First iteration
Delete All Example (3 of 8) kil->link = NULL; delete kil; }
A B C
item link item link item link
kil
frontsize
3
First iteration
Delete All Example (4 of 8) while (front != NULL) { kil = front; front = front->link;
B C
item link item link
kil
frontsize
3
Second iteration
Delete All Example (5 of 8) kil->link = NULL; delete kil; }
B C
item link item link
kil
frontsize
3
Second iteration
Delete All Example (6 of 8) while (front != NULL) { kil = front; front = front->link;
C
item link
kil
frontsize
3
Third iteration
Delete All Example (7 of 8) kil->link = 0; delete kil; }
C
item link
kil
frontsize
3
Third iteration
0
Delete All Example (8 of 8) size = 0;}
frontsize
0
Copy Constructors and Overloaded = Operators
• Copy constructors used to make copies when passing by value and returning by value in functions
• Operator = used for assignment
• Both have default behaviors if not user-defined, which is to do a bitwise copy of all member data
• The default behavior can be a problem when there are pointers in member data (shallow copying)
• Users should define their own copy constructor and overloaded operator = when they are creating a class with pointer data members
Deep Copying (1 of 3)
front
A B C 0
item link item link item linksize
3
slist1
slist2front
X Y 0
item link item linksize
2
• Consider the following two ShoppingList objects
• What would the result of slist2 = slist1; be if the default copy behavior took place?
Deep Copying (2 of 3)
front
A B C 0
item link item link item linksize
3
slist1
slist2front
X Y 0
item link item linksize
3
• slist2 becomes a “shallow copy” of slist1• slist2 doesn’t get a copy of slist1 data
• All references to slist2 data are lost (mem. leak)
Deep Copying (3 of 3)
front
A B C 0
item link item link item linksize
3
slist1
slist2frontsize
3
• Here is what slist2 would look like as a “deep copy” of slist1
• Note that slist2 has its own set of data
A B C 0
item link item link item link
Clone Example (1 of 8)void ShoppingList::clone(const ShoppingList &slist) { Node *cur1, *cur2;
front
A B C 0
item link item link item linksize
3
slist
*thisfront
X Y 0
item link item linksize
2
cur1
?
cur2
?
Clone Example (2 of 8) this->deleteAll(); this->size = slist.size;
front
A B C 0
item link item link item linksize
3
front
0
size
3
cur1
?
cur2
?slist
*this
Clone Example (3 of 8) this->front = new Node(*(slist.front));
front
A B C 0
item link item link item linksize
3
frontsize
3
cur1
?
cur2
?
A
item link
0
slist
*this
Clone Example (4 of 8) cur1 = this->front; cur2 = slist.front;
front
A B C 0
item link item link item linksize
3
frontsize
3
cur1 cur2
A
item link
0
slist
*this
Clone Example (5 of 8) while (cur2->link) { cur2 = cur2->link; cur1->link = new Node(*cur2); cur1 = cur1->link; }
front
A B C 0
item link item link item linksize
3
frontsize
3
cur1 cur2
A
item link
slist
*this
B
item link
0
First iteration
Clone Example (6 of 8) while (cur2->link) { cur2 = cur2->link; cur1->link = new Node(*cur2); cur1 = cur1->link; }
front
A B C 0
item link item link item linksize
3
frontsize
3
cur1 cur2
A
item link
slist
*this
B
item link
Second iteration
C 0
item link
Clone Example (7 of 8) cur1 = cur2 = 0;
front
A B C 0
item link item link item linksize
3
frontsize
3
cur1
0
cur2
0
A
item link
slist
*this
B
item link
C 0
item link
Clone Example (8 of 8)}
front
A B C 0
item link item link item linksize
3
frontsize
3 A
item link
slist
*this
B
item link
C 0
item link
Doubly Linked List
• Each node has 2 pointers, one to the node before and one to the node after
• No longer limited to left-to-right pointer movement
• Typically, a rear pointer is employed to simplify reverse traversals
front
A
data rlinkllink
B
data rlinkllink
C
data rlinkllink
rear
Circular Linked List
• “Last” node’s link points at the “front” node
• Concept of “front” optional (alternative: “current”)
cur
A
data link
B
datalink
Cdata
link
Edata
link
D
datalink