2. If the size of the data is not known before hand
◦ It means, at compile time or at the time of
object creation
Then
◦ Move towards dynamic implementation, the
size can be increased or decreased at the run-
time even as per need.
3. The linked list is a very flexible dynamic data
structure: items may be added to it or deleted
structure
from it at will.
A programmer need not worry about how many
items a program will have to accommodate.
This allows us to write robust programs which
require much less maintenance.
A very common source of problems in program
maintenance is the need to increase the
capacity of a program to handle larger
collections:
4. In a linked list, each item is allocated space as it is
added to the list.
A link is kept with each item to the next item in the
list.
Each node of the list has
two elements
1. the item being stored in
the list and
2. a pointer to the next
item in the list
The last node in the list contains a NULL pointer to indicate that it
is the end or tail of the list.
5. As items are added to a list, memory for a node is
dynamically allocated.
Thus the number of items that may be added to a
list is limited only by the amount of memory
available.
6. Handle for the list
The variable (or handle) which represents the list is
simply a pointer to the node at the head of the list.
This basic singly-linked list is inefficient in those cases
when we wish to add elements to both ends of the list.
It is easy to add elements at the head of the list,
To add elements at the other end (the tail ) we need to
locate the last element.
If the basic singly-linked list is used, the entire list needs to
be traversed in order to find its tail.
7. Following figure shows a way in which to make
adding elements to the tail of a list more
efficient.
The solution uses a second variable, tail ,
which refers to the last element of the list.
However, this time efficiency comes at the
cost of the additional space used to store the
variable tail.
8. The common operations on linked lists are:
1. AddToHead(x) Inserts element x in front of the
linked list .
2. AddToTail(x) Inserts element x at the end of the
linked list.
3. DeleteFromHead() Deletes the first element of
the linked list.
4. DeleteFromTail() Deletes the last element of the
linked list.
5. Delete(x) Deletes the node of value x from the
linked list.
6. Find(x) Find the entry x in the linked list.
7. print() prints the contents of the linked list.
8. And so on i.e.as many operations as you
required
9. Two cases must be considered to add the
node in front of the linked list.
1. Either we are creating the first node of
the linked list or
1. We are inserting the node in front of the
existing linked list.
10. First Case: Creating first node of a linked list.
We follow the following steps to create the first node of
the linked list.
1. Check the value of the head of the list.
If this value is null it means we are creating the first
node of the linked list.
2. An empty node is created.
It is empty in the sense that the program performing
insertion does not assign any values to the data
members of the node.
11. 3. The node's info member is initialized to a particular
value.
7
4. Since it is the only node of the linked list therefore its
next member will be initialized to null.
7 /
5. Since it is the only node of the linked list therefore
both head and tail points to this node of the linked list.
7 /
head tail
12. Second Case: Inserting node in front of
the existing linked list:
We follow the following steps to insert the node
in front of the existing linked list.
1. Check the value of the head of the list.
If this value is not null it means we are
inserting node in front of the existing linked
list.
7 /
head tail
13. 2. An empty node is created.
It is empty in the sense that the program
performing insertion does not assign any
values to the data members of the node.
7 /
head tail
14. 3. The node's info member is initialized to a particular value.
8 7 /
head tail
4. Because the node is being included at the front of the
list, the next member becomes a pointer to the first
node on the list, i.e. the current value of head.
8 7 /
head tail
15. 5. The new node precedes all the nodes on the list, but this
fact has to be reflected in the value of head; otherwise
the new node is not accessible. Therefore head is
updated to become the pointer to the new node
8 7 /
head tail
16. Two cases must be considered to add the
node at the end of a linked list.
1. Either we are creating the first node of the
linked list or
1. We are inserting the node at the end of an
existing linked list.
The first case is exactly similar as we
discussed in AddToHead(x) function.
17. Second Case: Inserting node at the end
of an existing linked list.
We follow the following steps to insert the node
at the end of an existing linked list.
1. Check the value of the head of the list.
If this value is not null it means linked list
already exists and we insert the node at the
end of an existing linked list.
8 7 /
head tail
18. 2. An empty node is created.
It is empty in the sense that the program
performing insertion does not assign any
values to the data members of the node.
8 7 /
head tail
19. 3. The node's info member is initialized to a particular value.
8 7 / 9
head tail
4. Because the node is being included at the end of the list, the
next member is set to null.
9
5. The node is now included in the list by making the next
member of the last node of the list a pointer to the newly
created node.
8 7 9
head tail
20. 6. The new node follows all the nodes of the list, but this fact has to
be reflected in the value of tail, which now becomes the pointer to
the new node.
8 7 9
head tail
21. Two cases must be considered to delete the
node from the head of a linked list.
1. Either a linked list has only one node or
1. A linked list has more than one nodes.
22. First Case: Linked List has only one
node:
We follow the following steps to handle this
case:
1. Check the values of the pointer variables
head and tail.
If both points to the same node, means
7 /
linked list has only one node. tail
head
2. Set both head and tail pointers to null and return
back the memory occupied by the node to the
system.
23. Second Case: Linked List has more
than one nodes
We follow the following steps to handle this
case:
1. Check the values of the pointer variables
head and tail.
If both points to the different nodes,
means linked list has more than one
nodes.
8 7 9
head tail
24. 2. Set a temporary pointer variable tmp points
to the head of a linked list.
8 7 9
head tail
tmp
3. Since we delete a node from the head of a linked
list, therefore move the head pointer to the node
next to the head of an existing list.
8 7 9
tail
tmp head
25. 4. Delete a node pointed by the pointer
variable tmp from a linked list.
8 7 9
tail
tmp head
7 9
tail
head
26. Two cases must be considered to delete the
node from the end of a linked list.
1. Either a linked list has only one node or
1. A linked list has more than one nodes.
The first case is exactly similar as we
discussed in DeleteFromHead() function.
27. Second Case: Linked List has more
than one nodes:
We follow the following steps to handle this
case:
1. Check the values of the pointer variables
head and tail.
If both points to the different nodes,
means linked list has more than one
nodes.
8 5 7 4 9
head tail
28. 2. After removing a node, tail should refer to
the new tail of the list. i.e. tail has to be
moved backward by one node.
8 5 7 4 9
head tail
8 5 7 4 9
head tail
But moving backward is impossible because
there is no direct link from the last node to its
predecessor.
29. 3. Hence, this predecessor has to be found by
searching from the beginning of the list and
stopping right before tail.
This is accomplished with a temporary
variable tmp used to scan a list within the
loop.
4. The variable tmp is initialized to the head of
8
the list.
5 7 4 9
head tail
tmp
30. 5. In each iteration of the loop, the variable
tmp is advanced to the next node of the
8
linked list.
5 7 4 9
head tail
tmp
After executing the assignment tmp= tmp->next,
tmp refers to the second node.
8 5 7 4 9
head tail
tmp
31. After the second iteration and executing the
same assignment, tmp refers to the third
8 node.5 7 4 9
head tail
tmp tmp tmp
After the third iteration and executing the same
assignment, tmp refers to the forth node.
Because next to this node is a last node, i.e. this
node is a predecessor of the last node, therefore
the loop is exited.
32. 6. Now delete the last node from the linked
list.
8 5 7 4 9
head tail
tmp
7. Because tail is now pointing to non existing
node therefore it is immediately set to point to
the node pointed by tmp.
8 5 7 4 /
head tail
tmp
8. To mark the fact that tail is now pointing to last
node of the linked list, the next member of this
node is set to null.
33. Two cases must be considered to delete the
node of value x from the linked list.
1. Either a linked list has only one node or
1. A linked list has more than one nodes.
The first case is exactly similar as we
discussed in DeleteFromHead() function
except
We first checks that the value of this single
node matches with the value of variable x.
34. Second Case: Linked List has more than
one nodes:
We follow the following steps to handle this case:
1. First matches the value of variable x with the value
of first node of the linked list.
If the value matches, it means we want to delete
first node of a linked list, therefore call the operation
DeleteFromHead().
2. Otherwise, match the value of variable x with the
value of last node of the linked list.
If the value matches, it means we want to delete
last node of a linked list, therefore call the operation
DeleteFromTail().
35. 3. If first two cases fails then locate the node whose
value matches with the value of variable x.
Such a node has to be found by searching from the
beginning of the list and stopping at the node
whose value matches with the value of variable x.
This is accomplished with a temporary variable tmp
used to scan a list within the loop.
The variable tmp is initialized to the head of the
linked list.
8 5 7 4 9
head tail
tmp
36. In each iteration of the loop, the value of the
node pointed by variable tmp will be
compared with the value of variable x.
If the value matches then we exited from
loop
Otherwise we advance the variable tmp to
compare the value of the next node of
linked list.
8 5 7 4 9
Consider the following linked list.
head tail
tmp
Suppose the value of the variable x is 4.
37. When we exited from the loop the variable
tmp is pointing to the node containing 4.
8 5 7 4 9
head tail
tmp
We can now remove a node pointed by variable
tmp by linking its predecessor to its successor.
But because the list has only forward links the
predecessor of a node is not reachable from the
node.
To locate the predecessor we again scan the list
from the beginning.
38. 4. This is accomplished with a temporary
variable pred used to scan a list within the
loop.
The variable pred is initialized to the head of
the linked list. 7
5 9
8 4
head tail
pred pred pred tmp
After executing the assignment pred=pred->next,
pred refers to the second node.
After the second iteration and executing the same
assignment, pred refers to the third node.
39. Because next to this node is a node pointed
by the variable tmp, i.e. this node is a
predecessor of the node pointed by variable
tmp, therefore the loop is exited.
8 5 7 4 9
head tail
pred tmp
5. Now join the node pointed by variable pred to
the node next to the node pointed by the variable
tmp.
40. 6. Now delete the node pointed by the variable
tmp from linked list.
8 5 7 4 9
head tail
pred tmp
8 5 7 9
head tail
pred
41. Every node of a linked list has two fields, an
information field and a field which points to
the next node of a list.
Therefore the class which for the node of a
list has two data members I.e.
◦ A data member to hold information &
◦ A data member which stores the address
of next node of a list
42. template<class T>
class Node {
public:
T info;
Node *next;
Node() {
next = 0;
}
Node(T el, Node *n = 0) {
info = el;
next = n;
}
};
43. Node *p = new Node(10);
Node *q = new Node(8);
p->next = q;
r = new Node(12);
q->next = r;
As we see this is an inconvenient and cumbersome
process.
Therefore
10 8 12 /
p q r
44. To implement the singly linked list we implement
two classes i.e.
◦ One class for nodes of the list &
◦ Another class for access to the list
45. template<class T>
class Node {
public:
T info;
Node *next;
Node() {
next = 0;
}
Node(T el, Node *n = 0) {
info = el;
next = n;
}
};
46. template<class T>
class SinglyLinkedList {
private:
Node<T> *head; //pointer to first node of a list
Node<T> *tail; //pointer to last node of a list
public:
SinglyLinkedList() {
head = tail = 0;
}
~SinglyLinkedList();
Continue on next slide…
47. bool isEmpty() {
if (head == 0) //list is empty
return true;
}
void addToHead(T el); //inserts an element in front of list
void addToTail(T el); //inserts an element at the end of list
void deleteFromHead(); //delete a node from the front of a list
an
void deleteFromTail(); //delete a node form the end of a list
void Delete(T el); //delete a node form list whose value is
el
Node *Find(T el); //Find the node from list whose value
is el //and returns its pointer.
void prints(); //prints the contents of a list
};
48. template<class T> void SinglyLinkedList<T> ::
addToHead(T el) head
{ Node *n = new Node<T>(e1, 0); //Creates new node
e
if (isEmpty) //first node of a list
head = tail = n; tail
n
else // Insert node in front of the list
{
n->next = head;
head
head = n;
}
e a b c d
} head head
n tail
49. template<class T>void
SinglyLinkedList<T>:: addToTail(T el)
head
{ Node *n = new Node<T>(e1, 0);
if(isEmpty) //Creates new
//First node of a list
node head = tail = n;
e
else //Insert node at the end of a list
tail
n
{
tail->next = n;
tail = n;
}
a b c d e
} head
tail tail n
50. template<class T>void SinglyLinkedList<T>::
deleteFromHead()
{ if(head != 0) //Non empty list
Node *n = head; head
If(head == tail) //if only one node in the list d
head = tail = 0; tail n
else
head = head->next; a b c d
delete n; head
n head tail
}
51. template<class T>void SinglyLinkedList<T>::
deleteFromTail()
{ if(head != 0) //Non empty list
if(head == tail) //Only one node in a list head
delete head;
{
head = tail = 0 d
}
else tail
{ Node *n = head;
while(n->next != tail) n = n->next;
delete tail; tail
tail = n;
a b c d
tail->next = 0;
head
} n n tail
52. template<class T>void SinglyLinkedList<T>::
Delete(T el)
{ if(head != 0) //Non empty list
if(el == head -> info)//we want to delete header
deleteFromHead();
node
else if(el == tail->info) //we want to delete last node
deleteFromTail();
Continue on next slide…..
53. else { //node we want to delete is not the header node and not the
tail //node
Node *tmp = head;
while(tmp != 0 && tmp ->info != el)//Locate the node we want to delete
tmp = tmp -> next;
If(tmp != 0) { //Node of value el exists
Node *pred = head;
while(pred ->next != tmp)//Locate the predecessor of node
//pointed by tmp
pred=pred->next;
pred->next = tmp->next;
a b c d
delete tmp;
head
} pred tmp tail
}
55. We can implement the stack dynamically using the linked list.
Declaration of type Dynamic Stack is:
template<class T>
class DynamicStack {
private:
Node<T> *top //pointer to top node of stack
public:
DynamicStack() {
top = 0; DynamicStack *s = new DynamicStack();
} s -> top
~DynamicStack();
Continue on next slide…..
Empty Stack
56. void push(T e1); //push element in stack
T pop(); //Pop element from stack
bool isEmpty() //Check stack is empty or not
{
if (top == 0)
return true
else
return false
}
T TopValue(); //Retruns top element of stack
};
57. s -> top
np New
Node
Empty Stack np New
np New Node
s -> top New Node
Node
s -> top
s -> top
Continuing this way we get the following link list.
New New New New
Node Node Node Node
s -> top
58. When we pop the stack then the node to
which top points will be popped and top
moves to the previous node.
But how top moves to previous node?
A node has no pointer to a previous node, it
only points to the next node
We can achieve this by placing the pointer of
previous node in a node, instead of placing
the pointer of next node in a node.
s -> top
59. template<class T>
class Node {
public:
T info;
Node *previous;
Node() {
previous = 0;
}
Node(T el, Node *n = 0) {
info = el;
previous = n;
}
};
60. void template<class T> DynamicStack ::
Push(T el)
Node *np = new Node<T>(e1);
{ np->previous = top;
top = np;
}
top np top
61. T template<class T> DynamicStack
::pop() = top;
Node *np
{
top = np -> previous;
return np -> info;
}
top top np
62. Reversing the string
void ReverseRead (void)
{ DynamicStack * stack = new DynamicStack(); //The stack stack is
created //and can
hold elements of
//type char
char item;
cin>>item;
while (item ! = “n”)
{ stack->Push (item); // push each character onto the stack
cin>>item;
}
while(! stack->is_Empty() )
{ item = stack->Pop (); //Pop an element from stack
cout<<item;
}