List Using Linked Memory: Various Cells of Memory Are Not Allocated Consecutively in Memory
List Using Linked Memory: Various Cells of Memory Are Not Allocated Consecutively in Memory
List Using Linked Memory: Various Cells of Memory Are Not Allocated Consecutively in Memory
Linked List
Create a structure called a Node.
object next
Linked List
Picture of our list (2, 6, 7, 8, 1) stored as a linked list:
head 2 6 current 8 7 1 size=5
Linked List
Note some features of the list: Need a head to point to the first node of the list. Otherwise we wont know where the start of the list is.
Linked List
Note some features of the list: Need a head to point to the first node of the list. Otherwise we wont know where the start of the list is. The current here is a pointer, not an index.
Linked List
Note some features of the list: Need a head to point to the first node of the list. Otherwise we wont know where the start of the list is. The current here is a pointer, not an index. The next field in the last node points to nothing. We will place the memory address NULL which is guaranteed to be inaccessible.
Linked List
Actual picture in memory:
1051 1052 current 1053 1054 1055 1056 6 1063 1063 2 1051 7 1060 1
head 2 6 8 current 7 1
1061
head 1062 1063 1064 1065
0
1054 8 1057
8
2
7
1
size=5 6
9
newNod e
#include "Node.cpp" class List { public: // Constructor List() { headNode = new Node(); headNode->setNext(NULL); currentNode = NULL; size = 0; };
public: // Constructor List() { headNode = new Node(); headNode->setNext(NULL); currentNode = NULL; size = 0; };
void add(int addObject) { Node* newNode = new Node(); newNode->set(addObject); if( currentNode != NULL ){ newNode->setNext(currentNode->getNext()); currentNode->setNext( newNode ); lastCurrentNode = currentNode; currentNode = newNode; } else { newNode->setNext(NULL); headNode->setNext(newNode); lastCurrentNode = headNode; currentNode = newNode; } size++; };
list.add(2);
headNode lastcurrentNode
size=1
list.add(2);
headNode lastcurrentNode
size=1
currentNode
list.add(6);
headNode
size=2
lastcurrentNode
lastcurrentNode
2
2
size=4
lastcurrentNode
remove
find
worst-case: may have to search the entire list back moving the current pointer back one node requires traversing the list from the start until the node whose next pointer points to current node.
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 the head of the singly-linked list and move forward until the node before the current. To avoid this we can use two pointers in a node: one to point to next node and another to point to the previous node:
prev element next
Doubly-linked List
Need to be more careful when adding or removing a node. Consider add: the order in which pointers are reorganized is important:
head
size=5
current
Doubly-linked List
1. 2. 3. 4. newNode->setNext( current->getNext() ); newNode->setprev( current ); (current->getNext())->setPrev(newNode); current->setNext( newNode );
current
head
2
2
6
4 3
size=5
newNode
Doubly-linked List
1. 2. 3. 4. 5. 6. newNode->setNext( current->getNext() ); newNode->setprev( current ); (current->getNext())->setPrev(newNode); current->setNext( newNode ); current = newNode; size++;
head 2
2
6
4 3
size=6
newNode
current
Circularly-linked lists
The next field in the last node in a singly-linked list is set to NULL. Moving along a singly-linked list has to be done in 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 the last node with the first node in the list to create a circularly-linked list.
Josephus Problem
A case where circularly linked list comes in handy is the solution of the Josephus Problem. Consider there are 10 persons. They would like to choose a leader. The way they decide is that all 10 sit in a circle. They start a count with person 1 and go in clockwise direction and skip 3. Person 4 reached is eliminated. The count starts with the fifth and the next person to go is the fourth in count. Eventually, a single person remains.
Josephus Problem
N=10, M=3
5 8 2 7 3 10 9 1 6
eliminated
4
Josephus Problem
#include "CList.cpp" void main(int argc, char *argv[]) { CList list; int i, N=10, M=3; for(i=1; i <= N; i++ ) list.add(i); list.start(); while( list.length() > 1 ) { for(i=1; i <= M; i++ ) list.next(); cout << "remove: " << list.get() << endl; list.remove(); } cout << "leader is: " << list.get() << endl; }