62
Linked Lists

Data Structure Lecture 5

  • Upload
    iiui

  • View
    404

  • Download
    0

Embed Size (px)

DESCRIPTION

Link list.

Citation preview

Page 1: Data Structure Lecture 5

Linked Lists

Page 2: Data Structure Lecture 5

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.

Page 3: Data Structure Lecture 5

The linked list is a very flexible dynamic dynamic data structuredata structure: items may be added to it or deleted 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:

Page 4: Data Structure Lecture 5

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.

Page 5: Data Structure Lecture 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.

Page 6: Data Structure Lecture 5

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 This basic singly-linked list is inefficient in those cases when we wish to add elements to both ends of the list.when we wish to add elements to both ends of the list.

It is easy to add elements at the head of the list, It is easy to add elements at the head of the list, To add elements at the other end (the To add elements at the other end (the tailtail ) we need to  ) we need to

locate the last element.locate the last element. If the basic singly-linked list is used, the entire list needs to If the basic singly-linked list is used, the entire list needs to

be traversed in order to find its tail.be traversed in order to find its tail.

Page 7: Data Structure Lecture 5

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, The solution uses a second variable, tail tail , , which refers to the last element of the list. which refers to the last element of the list.

However, this time efficiency comes at the However, this time efficiency comes at the cost of the additional space used to store the cost of the additional space used to store the variable tail. variable tail.

Page 8: Data Structure Lecture 5

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

Page 9: Data Structure Lecture 5

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.

Page 10: Data Structure Lecture 5

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.

Page 11: Data Structure Lecture 5

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

Page 12: Data Structure Lecture 5

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

Page 13: Data Structure Lecture 5

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

Page 14: Data Structure Lecture 5

3. The node's info member is initialized to a particular value.

7 /

head tail 8

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.

7 /

head tail 8

Page 15: Data Structure Lecture 5

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

7 /

tailhead 8

Page 16: Data Structure Lecture 5

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.

Page 17: Data Structure Lecture 5

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.

7 /

tailhead 8

Page 18: Data Structure Lecture 5

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 /

tailhead 8

Page 19: Data Structure Lecture 5

3. The node's info member is initialized to a particular value.

7 /

tailhead 8

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.

9 \ 7

tailhead 8

9

Page 20: Data Structure Lecture 5

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.

9 \ 7

head tail 8

Page 21: Data Structure Lecture 5

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.

Page 22: Data Structure Lecture 5

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 linked list has only one node.

7 /

head tail2.2. Set both Set both headhead and and tail tail pointers to pointers to nullnull and return and return

back the memory occupied by the node to the back the memory occupied by the node to the system.system.

Page 23: Data Structure Lecture 5

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.

9 \ 7

head tail 8

Page 24: Data Structure Lecture 5

2. Set a temporary pointer variable tmp points to the head of a linked list.

9 \ 7

head tail 8

tmp

3.3. Since we delete a node from the head of a linked Since we delete a node from the head of a linked list, therefore move the list, therefore move the head head pointer to the node pointer to the node next to the head of an existing list.next to the head of an existing list.

9 \ 7

head tail 8

tmp

Page 25: Data Structure Lecture 5

4. Delete a node pointed by the pointer variable tmp from a linked list.

9 \ 7

head tail 8

tmp

9 \ 7

head tail

Page 26: Data Structure Lecture 5

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.

Page 27: Data Structure Lecture 5

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.

9 \ 7

head tail 8 4 5

Page 28: Data Structure Lecture 5

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. 9 \ 7

head tail 8 4 5

9 \ 7

head tail

8 4 5

But moving backward is impossible because But moving backward is impossible because there is no direct link from the last node to its there is no direct link from the last node to its predecessor.predecessor.

Page 29: Data Structure Lecture 5

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 the list.

9 \ 7

head tail 8 4 5

tmp

Page 30: Data Structure Lecture 5

5. In each iteration of the loop, the variable tmp is advanced to the next node of the linked list.

9 \ 7

head tail 8 4 5

tmp

After executing the assignment After executing the assignment tmp= tmp->next, tmp= tmp->next, tmp tmp refers to the second node.refers to the second node.

9 \ 7

head tail 8 4 5

tmp

Page 31: Data Structure Lecture 5

After the second iteration and executing the same assignment, tmp refers to the third node. 9 \ 7

head tail 8 4 5

tmp tmptmp

After the third iteration and executing the same After the third iteration and executing the same assignment, assignment, tmp tmp refers to the forth node.refers to the forth node.

tmptmp

Because next to this node is a last node, i.e. this Because next to this node is a last node, i.e. this node is a predecessor of the last node, therefore node is a predecessor of the last node, therefore the loop is exited.the loop is exited.

Page 32: Data Structure Lecture 5

6. Now delete the last node from the linked list.

9 \ 7

head tail 8 4 5

tmp7.7. Because Because tail tail is now pointing to non existing is now pointing to non existing

node therefore it is immediately set to point to node therefore it is immediately set to point to the node pointed by the node pointed by tmp.tmp.

7

head tail 8 4 / 5

tmp8.8. To mark the fact that To mark the fact that tailtail is now pointing to last is now pointing to last

node of the linked list, the next member of this node of the linked list, the next member of this node is set to node is set to nullnull..

Page 33: Data Structure Lecture 5

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.

Page 34: Data Structure Lecture 5

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().

Page 35: Data Structure Lecture 5

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. 9 \ 7

head tail 8 4 5

tmp

Page 36: Data Structure Lecture 5

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 loopOtherwise we advance the variable tmp to compare the value of the next node of linked list.Consider the following linked list. 9 \ 7

head tail 8 4 5

tmp

Suppose the value of the variable Suppose the value of the variable x x is is 4.4.

Page 37: Data Structure Lecture 5

When we exited from the loop the variable tmp is pointing to the node containing 4. 9 \ 7

head tail 8 4 5

tmpWe can now remove a node pointed by variable We can now remove a node pointed by variable tmptmp by linking its predecessor to its successor. by linking its predecessor to its successor.

But because the list has only forward links the But because the list has only forward links the predecessor of a node is not reachable from the predecessor of a node is not reachable from the node.node.

To locate the predecessor we again scan the list To locate the predecessor we again scan the list from the beginning. from the beginning.

Page 38: Data Structure Lecture 5

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.

9 \ 7

head tail 8 4 5

tmppred

After executing the assignment After executing the assignment pred=pred->next, pred=pred->next, pred pred refers to the second node.refers to the second node.

predpred predpred

After the second iteration and executing the same After the second iteration and executing the same assignment, assignment, pred pred refers to the third node.refers to the third node.

Page 39: Data Structure Lecture 5

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. 9 \ 7

head tail 8 4 5

tmppred

5.5. Now join the node pointed by variable Now join the node pointed by variable predpred to to the node next to the node pointed by the variable the node next to the node pointed by the variable tmp.tmp.

Page 40: Data Structure Lecture 5

6. Now delete the node pointed by the variable tmp from linked list.

9 \ 7

head tail 8 4 5

tmppred

9 \ 7

head tail 8 5

pred

Page 41: Data Structure Lecture 5

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

Page 42: Data Structure Lecture 5

template<class T>class Node {public:

T info;Node *next;Node() {

next = 0;}Node(T el, Node *n = 0) {

info = el;next = n;

}};

Page 43: Data Structure Lecture 5

Node *p = new Node(10);Node *p = new Node(10);

10

p

Node *q = new Node(8);

8

q

p->next = q;r = new Node(12);

12 /

r

q->next = r;As we see this is an inconvenient and cumbersome process.

Therefore

Page 44: Data Structure Lecture 5

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

Page 45: Data Structure Lecture 5

template<class T>class Node {public:

T info;Node *next;Node() {

next = 0;}Node(T el, Node *n = 0) {

info = el;next = n;

}};

Page 46: Data Structure Lecture 5

template<class T>class SinglyLinkedList {

private:Node<T> *head; //pointer to first node of a //pointer to first node of a

listlistNode<T> *tail; //pointer to last node of a //pointer to last node of a

listlistpublic:

SinglyLinkedList() {head = tail = 0;

}~SinglyLinkedList();

Continue on next slide…

Page 47: Data Structure Lecture 5

bool isEmpty() {if (head == 0) //list is empty//list is empty

return true;}void addToHead(T el); //inserts an element in front of list//inserts an element in front of listvoid addToTail(T el); //inserts an element at the end of list//inserts an element at the end of listvoid deleteFromHead(); //delete a node from the front //delete a node from the front

of a list anof a list anvoid deleteFromTail(); //delete a node form the end of a list //delete a node form the end of a list void Delete(T el); //delete a node form list whose //delete a node form list whose

value is elvalue is elNode *Find(T el); //Find the node from list whose //Find the node from list whose

value is el value is el //and returns its pointer.//and returns its pointer.void prints(); //prints the contents of a list//prints the contents of a list};

Page 48: Data Structure Lecture 5

template<class T> void SinglyLinkedList<T> :: addToHead(T el)

{ Node *n = new Node<T>(e1, 0); //Creates new //Creates new nodenode

tail

head

if (isEmpty)if (isEmpty) //first node of a list//first node of a list

head = tail = n;head = tail = n;

elseelse // Insert node in front of the list// Insert node in front of the list{{

n

e ahead

b c d

tail

n

e

n->next = headn->next = head;head = n;head = n;

head

}

}

Page 49: Data Structure Lecture 5

template<class T>void SinglyLinkedList<T>::addToTail(T el)

{ Node *n = new Node<T>(e1, 0); //Creates new node//Creates new node

n

e

tail

headif(isEmpty)if(isEmpty) //First node of a list//First node of a list

head = tail = n;head = tail = n;

elseelse //Insert node at the end of a list//Insert node at the end of a list

{{

n

eahead

b c d

tail

tail->next = n;tail->next = n;tail = n;tail = n;

tail

}

}

Page 50: Data Structure Lecture 5

template<class T>void SinglyLinkedList<T>:: deleteFromHead()

{if(head != 0) //Non empty list//Non empty listNode *n = head;Node *n = head;

If(head == tail)If(head == tail) //if only one node in the list//if only one node in the list

n

d

tail

head

elseelse

ahead

b c d

tailn

head = head->next;head = head->next;

head delete n;delete n;

}

head = tail = 0;head = tail = 0;

Page 51: Data Structure Lecture 5

template<class T>void SinglyLinkedList<T>:: deleteFromTail()

{ if(head != 0) //Non empty list//Non empty list if(head == tail) //Only one node in a list//Only one node in a list {

ahead

b c d

tailn

elseelse{{ Node *n = head;Node *n = head;

while(n->next != tail) n = n->next;while(n->next != tail) n = n->next;

n

tail = n;tail = n;

delete tail;delete tail;

tail->next = 0;

}

}

d

tail

headdelete head; head = tail = 0head = tail = 0}}

tail

Page 52: Data Structure Lecture 5

template<class T>void SinglyLinkedList<T>:: Delete(T el)

{if(head != 0) //Non empty list//Non empty listif(el == head -> info)//we want to delete header //we want to delete header

node node deleteFromHead();

Continue on next slide…..

else if(el == tail->info) //we want to delete last node //we want to delete last node deleteFromTail();

Page 53: Data Structure Lecture 5

else { //node we want to delete is not the header node and not the tail //node we want to delete is not the header node and not the tail //node//node

Node *tmp = head;while(tmp != 0 && tmp ->info != el)//Locate the node we want to delete//Locate the node we want to delete

tmp = tmp -> next;

a

head

b c d

tail

If(tmp != 0) { //Node of value el exists//Node of value el exists

pred->next = tmp->next;

pred

delete tmp; } }

tmp

Node *pred = head;while(pred ->next != tmp)//Locate the predecessor of node //Locate the predecessor of node

//pointed by tmp//pointed by tmppred=pred->next;pred=pred->next;

Page 54: Data Structure Lecture 5

template<class T>void SinglyLinkedList<T> ::

~SinglyLinkedList(){

if(!isEmpty()) //List is not empty//List is not emptywhile(head != 0)

deleteFromHead();}

Page 55: Data Structure Lecture 5

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 //pointer to top node of

stackstackpublic:

DynamicStack() {top = 0;

}~DynamicStack();

s -> top

Empty Stack

DynamicStack *s = new DynamicStack();

Continue on next slide…..

Page 56: Data Structure Lecture 5

void push(T e1); //push element in stack//push element in stackT pop(); //Pop element from stack//Pop element from stackbool isEmpty() //Check stack is empty or not//Check stack is empty or not{

if (top == 0)return true

elsereturn false

}T TopValue(); //Retruns top element of stack//Retruns top element of stack};

Page 57: Data Structure Lecture 5

s -> top

Empty Stacknp

NewNodeNew

Node

s -> top

npNewNode

s -> tops -> top

npNewNode

NewNode

s -> top

NewNode

NewNode

NewNode

Continuing this way we get the following link list.

Page 58: Data Structure Lecture 5

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

Page 59: Data Structure Lecture 5

template<class T>class Node {public:

T info;Node *previous;Node() {

previous = 0;}Node(T el, Node *n = 0) {

info = el; previous = n;

}};

Page 60: Data Structure Lecture 5

void template<class T> DynamicStack :: Push(T el)

{

top

Node *np = new Node<T>(e1);

np

np->previous = top; top = np;}

top

Page 61: Data Structure Lecture 5

T template<class T> DynamicStack ::pop()

{

np

Node *np = top;

top

top = np -> previous; return np -> info;}

top

Page 62: Data Structure Lecture 5

Reversing the stringvoid ReverseRead (void){ DynamicStack * stack = new DynamicStack(); //The stack //The stack stack stack is created is created

//and can hold elements of //and can hold elements of //type char //type charchar item;cin>>item;while (item ! = “\n”){ stack->Push (item); // push each character onto the stack // push each character onto the stack

cin>>item;}while(! stack->is_Empty() ){ item = stack->Pop (); //Pop an element from stack//Pop an element from stack

cout<<item;}

}