Lectures 2 – 6
Implementing Lists
We have designed the interface for the List; wenow must consider how to implement that interface.
Implementing Lists using an array: for example,the list of integers (2, 6, 8, 7, 1) could be represented as:
A 6 8 7 1
1 2 3 4 5
List Implementation
add(9); current position is 3. The new list would thus be: (2, 6, 8, 9, 7, 1)
We will need to shift everything to the right of 8 one place to the right to make place for the new element ‘9’.
current 3
size 5
step 1: A 6 8 7 1
1 2 3 4 5
2 6 current 4 size 6
step 2: A 6 8 7 1
1 2 3 4 5
2
6 9
Implementing Lists
next():current 4
size 6
A 6 8 7 1
1 2 3 4 5
2
6 9
Implementing Lists
remove(): removes the element at the currentindex
current 5
size 6
A 6 8 1
1 2 3 4 5
2 6 9 5 Step 1: current 5 size 5
A 6 8 1
1 2 3 4 5
2 9
Implementing Lists
remove(): removes the element at the currentindex
We fill the blank spot left by the removal of 7 by
shifting the values to the right of position 5 over to the left one space.
current 5
size 5
A 6 8 1
1 2 3 4 5
2 9 Step 2: current 5 size 6
A 6 8 1
1 2 3 4 5
2
6 9
5
Implementing Lists
find(X): traverse the array until X is located.
int find(int X) {
int j;
for(j=1; j < size+1; j++ ) if( A[j] == X ) break;
if( j < size+1 ) { // found X
current = j; // current points to where X found return 1; // 1 for true
}
Implementing Lists
Other operations:get() return A[current];
update(X) A[current] = X;
length() return size;
back() current--;
start() current = 1;
Analysis of Array Lists
add we have to move every element to the right of
current pointer to make space for the new element.
Worst-case is when we insert at the beginning; we
have to move every element right one place.
Best case is when the current is pointing to the last element of the list
Average-case: on average we may have to move
Analysis of Array Lists
remove
Worst-case: remove at the beginning, mustshift all remaining elements to the left.
Best case is when the current is pointing tothe last element of the list
Average-case: expect to move half of theAnalysis of Array Lists
Find ()
What is the worst case?
Best case?Analysis of Array Lists
Find()
Worst-case: may have to search the entirearray. The desired elements is the last element of the list.
Best case is when the location of the desiredelement is at the first is the list
Analysis of Array Lists
Which of the list operations are One-stepAnalysis of Array Lists
How about the following operations?get() return A[current];
update(X) A[current] = X;
length() return size;
back() current--;
start() current = 1;
List
Using
Linked Memory
Various cells of memory are not allocated consecutively
in memory.
An array may not be enough to store the elements of the list.
With arrays, the second element was right next to the
first element.
Now the first element must explicitly tell us where to
look for the second element.
Linked List
Create a structure called a Node.object next
The object field will hold the actual list element. The next field in the structure will hold the
starting location of the next node.
Linked List
Picture of our list (2, 6, 7, 8, 1) stored as alinked list:
2 6 8 7 1
head
current
Linked List
Note some features of the linked list:
Need a head pointer to point to the first node ofthe list. Otherwise we won’t know where is the
Linked List
Note some features of the linked list:
Need a head node to point to the first node ofthe list. Otherwise we won’t know where is the
start of the list.
Linked List
Note some features of the linked list:
Need a head node to point to the first node ofthe list. Otherwise we won’t know where is the
start of the list.
The current here is a pointer, not an index.
The next field in the last node points to nothing.Linked List
Actual picture in memory:1051 1052 1055 1059 1060 1061 1062 1063 1064 1056 1057 1058 1053 1054 2 6 8 7 1 1051 1063 1057 1060 0 head 1054 1063 current
2 6 8 7 1
head
current
Linked List
Actual picture in memory:1051 1052 1055 1059 1060 1061 1062 1063 1064 1056 1057 1058 1053 1054 2 6 8 7 1 1051 1063 1057 1060 0 head 1054 1063 current
2 6 8 7 1
head
current
1065
What will be result of
Linked List Operations
add(9): Create a new node in memory to hold ‘9’ Node* newNode = new Node(9);
Linked List Operations
add(9): Create a new node in memory to hold ‘9’Node* newNode = new Node(9);
Link the new node into the list
9 newNode
2 6 8 7 1
head
current
size=5 6
9
newNode
1 3
Building a Linked List
headNode size=0
Building a Linked List
headNode
2 headNode
currentNode
size=1
lastcurrentNode
size=0
List list;
Building a Linked List
headNode
2 headNode
currentNode
size=1
lastcurrentNode
2 6 headNode
currentNode
size=2
lastcurrentNode
size=0
List list;
list.add(2);
Building a Linked List
List.add(8); list.add(7); list.add(1);
2 6 7 1
headNode
currentNode
size=5
void remove() {
if( currentNode != NULL &&
currentNode != headNode) {
lastCurrentNode->setNext(currentNode->getNext());
delete currentNode;
currentNode = lastCurrentNode->getNext();
size--;
}
};
2 6 7 1
headNode
currentNode
size=5
lastcurrentNode
8
Removing a node from Linked list
void remove() {
if( currentNode != NULL &&
currentNode != headNode) {
lastCurrentNode->setNext(currentNode->getNext());
delete currentNode;
currentNode = lastCurrentNode->getNext();
size--;
}
};
2 6 7 1
headNode
currentNode
size=5
lastcurrentNode
void remove() {
if( currentNode != NULL &&
currentNode != headNode) {
lastCurrentNode->setNext(currentNode->getNext());
delete currentNode;
currentNode = lastCurrentNode->getNext();
size--;
}
};
2 7 1
headNode
currentNode
size=5
lastcurrentNode
8
void remove() {
if( currentNode != NULL &&
currentNode != headNode) {
lastCurrentNode->setNext(currentNode->getNext());
delete currentNode;
currentNode = lastCurrentNode->getNext();
size--;
}
};
2 7 1
headNode
currentNode
size=4
lastcurrentNode
8
Analysis of Linked List
add
• we simply insert the new node after the current node. So add is a one-step
Analysis of Linked List
add
• we simply insert the new node after the current node. So add is a one-step
operation.
remove
remove is also a one-step operation Find
Analysis of Linked List
add
• we simply insert the new node after the current node. So add is a one-step
operation.
remove
remove is also a one-step operation Find
worst-case: may have to search the entire
Analysis of Linked List
add
• we simply insert the new node after the current node. So add is a one-step operation.
remove
remove is also a one-step operation find
worst-case: may have to search the entire list back
moving the current pointer back one node
Doubly-linked List
Moving forward in a singly-linked list is easy;Doubly-linked List
Moving forward in a singly-linked list is easy;moving backwards is not so easy.
To move back one node, we have to start at theDoubly-linked List
Moving forward in a singly-linked list is easy;moving backwards is not so easy.
To move back one node, we have to start at thehead of the singly-linked list and move forward until the node before the current.
To avoid this we can use two pointers in anode: one to points to next node and another to points to the previous node:
Doubly-linked List
Need to be more careful when adding orremoving a node.
Consider add: the order in which pointers arereorganized is important:
size=5
2 6 8 7 1
head
current
What will be result of
Doubly-linked List
1. newNode->setNext( current->getNext() );
size=5
2 6 8 7
head
current
1
9
Doubly-linked List
1. newNode->setNext( current->getNext() );
2. newNode->setprev( current );
size=5
2 6 8 7
head
current
1
9
Doubly-linked List
1. newNode->setNext( current->getNext() );
2. newNode->setprev( current );
3. (current->getNext())->setPrev(newNode);
size=5
2 6 8 7
head
current
1
9
Doubly-linked List
1. newNode->setNext( current->getNext() );
2. newNode->setprev( current );
3. (current->getNext())->setPrev(newNode);
4. current->setNext( newNode );
size=5
2 6 8 7
head
current
1
9
Doubly-linked List
1. newNode->setNext( current->getNext() );
2. newNode->setprev( current );
3. (current->getNext())->setPrev(newNode);
4. current->setNext( newNode );
5. current = newNode;
6. size++;
size=6
2 6 8 7
head
current
1
9
Circularly-linked lists
The next field in the last node in a singly-linkedlist is set to NULL.
Moving along a singly-linked list has to be donein a watchful manner.
Doubly-linked lists have two NULL pointers:prev in the first node and next in the last node.
A way around this potential hazard is to link theCircularly-linked lists
The next field in the last node in a singly-linkedlist is set to NULL.
Moving along a singly-linked list has to be donein a watchful manner.
Doubly-linked lists have two NULL pointers:prev in the first node and next in the last node.
A way around this potential hazard is to link theCircularly-linked lists
The next field in the last node in a singly-linkedlist is set to NULL.
Moving along a singly-linked list has to be donein a watchful manner.
Doubly-linked lists have two NULL pointers:prev in the first node and next in the last node.
A way around this potential hazard is to link theCircularly-linked lists
The next field in the last node in a singly-linkedlist is set to NULL.
Moving along a singly-linked list has to be donein a watchful manner.
Doubly-linked lists have two NULL pointers:prev in the first node and next in the last node.
A way around this potential hazard is to link thelast node with the first node in the list to create
Circularly Linked List
Two views of a circularly linked list:2 6 8 7 1
head
current
size=5
2
8
7
1
head
current
size=5
Advantages of Linked List
Linked lists are a dynamic data structure, which can
grow and be pruned, allocating and deallocating memory while the program is running.
Insertion and deletion node operations are easily
implemented in a linked list.
Dynamic data structures such as stacks and queues
can be implemented using a linked list.
There is no need to define an initial size for a Linked
list.
Items can be added or removed from the middle of list.
Disadvantages of Linked
List
They use more memory than arrays because of the
storage used by their pointers.
Nodes in a linked list must be read in order from the
beginning as linked lists are inherently sequential access.
Nodes are stored incontiguously, greatly increasing the
time required to access individual elements within the list, especially with a CPU cache.
Difficulties arise in linked lists when it comes to reverse
traversing. For instance, singly linked lists are
cumbersome to navigate backwards and while doubly linked lists are somewhat easier to read, memory is