01 linked lists

Upload: amitfegade121

Post on 07-Jan-2016

221 views

Category:

Documents


0 download

DESCRIPTION

Linked list notes

TRANSCRIPT

DS - DSAA ( Common Topics )

1. Linked Lists

Lists:

In general lists are like arrays that are used to store ordered data. A List is a linear sequence of data objects of same type.

Or

List is a collection of multiple elements arranged one after another in linear order.

Common operations on list :

Creating an initial list.

Inserting new elements in the list at any position.

Deleting any elements from list.

Displaying i.e. printing elements in list. (usually from 1st to last ) Searching given element in the list.

Arranging elements in the list according value of the elements. (Sorting a list).

Linked Lists :

(Using Dynamic memory allocation i.e. Node implementation) :

Linked list is an ordered collection of data in which each element holds a link for the next element in the list.

Each element contains data and the reference for the next element; that is each element contains two parts data and a link. The data part holds the useful information ( i.e. the data to be processed). The link is used to chain the list elements together. An element that holds Data and a Link for other elements is called a Node.

According to type of list there can be one or two links in each node.

Its dynamic structure and any number of Nodes can be added to it. It uses Dynamic memory allocation to create new Nodes.

Thus linked list is a linear collection of Nodes where each node holds link for next Node in the list. The first node holds link for the second node, second holds link for third and so on. The last Node holds Null link to indicate its a last element in the list.

Each node consists of two main fields: Information i.e. Data and Link i.e. Reference for next element.

For example, a linked list created to store student information may have students roll no, name and height as an information field in a node. Link is nothing but a reference i.e. memory address of a node. In C programs link is a Pointer for a node.

Types of Linked Lists :Singly linked list :

Singly linked list consists of one or more nodes with each node holding reference for a next element in the list. The last node holds a null reference to indicate end of a list. The reference for the first node is kept in a reference variable called root. New nodes can be added to the list and any existing nodes can be removed.

One can traverse the list from in forward direction in the list. Following figure shows a Singly linked list with four elements i.e. nodes with data A, B, C and D. A is first node and D is a last node.

Black filled circles indicate links to next nodes and hollow circle indicates null link.

Circular Linked List :

Circular linked list consists of one or more nodes with each node holding reference (pointer) for a next element in the list.

The last node holds a reference to the root i.e. first node of a list.

The reference for the first node is kept in a reference variable called root. New nodes can be added to the list and any existing nodes can be removed.

One can traverse the list in forward direction but circularly.Following figure shows a Circular linked list with four elements i.e. nodes with data A, B, C and D. A is first node and D is a last node.

Black filled circles indicate links to next nodes.

Doubly Linked List :

Doubly linked list consists of one or more nodes with each node holding references (pointers) for next and previous elements in the list.

Each node has two link fields ( i.e. two pointers). The pointers are called as forward (next) pointer and backward (previous) pointer.

The forward pointer of last node and backward pointer of root hold Null.

The reference for the first node is kept in a reference variable called root. New nodes can be added to the list and any existing nodes can be removed.

One can traverse the list in forward direction as well as backward direction. Thus, from any nth node in a list we can move towards root or towards end of list. Thus, the list is more flexible.Following figure shows a Doubly linked list with four elements i.e. nodes with data A, B, C and D. A is first node and D is a last node.

Black filled circles indicate links to next/previous nodes.

Singly Linked List :Adding an element (node) to the list:

The new node will hold null link to indicate its a last node. An algorithm for adding a node to a singly linked list is given below,

A-1

1.Input the data to be stored in the node.

2.Allocate memory for new node.

3.Store data in the information field and null in the link field in a new node.

4.If list is empty (if its a first node)

Store reference for the node in variable, root.

6.Else

Put reference for the new node in the link field of currently last node.

7.Record new node as last node of ListDisplaying linked list elements:

To display the nodes in a list first get the reference of root of the list. Display the contents (information field) of the root node. Read the link field of the node, which gives reference for the next node. Display the contents of the node given by this link. Repeat the process till end of list is reached.

Algorithm for displaying the list contents is as follows,

A 2

1.Read the root into a reference variable (pointer)

2.While pointer is not Null repeat following.

a. Display contents of node referred by the pointer

b. Update the pointer to pointer value in current node.

Removing a node from a list:

Here, input the node value to remove (i.e. delete). Find the node. Then link the next node to the previous node of the list. e.g. to remove fourth node of linked list, one has link the third node to fifth node.

There are three cases: i) Remove first node, ii)Remove last node and iii) Remove intermediate node. The following algorithm shows all the cases.

Algorithm to remove an item from the list,

A-3

1.Input the node value to be deleted

2.Read the root pointer

3.While pointer is not Null repeat following

a.If node to deleted is found, then,

Stop the search

b. Else

Read pointer for next node

4. If required node is found in above step 3 then

i.If it is root node

Update root of list to refer the second node in the list

ii. Else if its a last node then

Make second last node as last node

(i.e. perform following operations)

Put Null in the link field of previous node.

iii.Else

Update link in the previous node to address of the next node

iv.Free the node to be deleted.

5. If node not found display (error) message

Inserting Node (before given node):

Node can be inserted in the list at whatever position without making many changes in the existing list.

To insert a node at the place of an node A, existing in a list: Create a new node (allocate a new node) in memory, and update the links in the corresponding nodes. e.g. to insert B node between A and C, one has to link A to B and B (new node) to C.

If a node is inserted at the beginning of a list the new node becomes a root of the list and the previous root node of the list becomes a second node.

An algorithm to insert a node in the list is as follows,

A-4

1. Read root pointer of list2. Input the node value before which new node will be inserted

3. Input value for a new node

4.While pointer note null (i.e. not end of a list) repeat following

a.If the node found where new node is to be inserted then

Stop the search

b.Else

Read pointer for next node

5. If node is found in step 4, then

i.Allocate memory for new node

ii.Store information in the node and link for the current node

iii.If inserting at the beginning of list then

Make new node as root and original root node as second node

iv.Else

Update pointer in previous node to refer to new node and pointer in new

node to the refer to the node before which new node was inserted.

6.If node not found display (error) message.

Note :

Complete program for Singly Linked List will be Discussed and Written in class.Static and Dynamic implementation of Linked List :

Linked list can be formed by creating linking nodes in linear order. This is also called a dynamic implementation of Lists.

In static implementation, a list can be created using an array. Its a simplest implementation of lists. List items can be stored in an array in continuous elements and any item in the list can be accessed using syntax array_name[index].

A new element can be added at the end of the existing list by just keeping track of the last element index.

Now lets see the Insert operation. Suppose we have to insert an item at Nth position. To do this we must shift elements from Nth position till the last element in the list, by one position towards the end of the array.

Similarly, to delete an element at Nth position we have to shift all the elements from (N+1)th position till the end of the list, towards the beginning of array by one.

Thus, to insert or delete an item in a list, lot of movement of data is required which is always undesirable.

Drawbacks of array implementation of a List are as follows,

An array is created taking into consideration certain number of elements.The allocated memory storage space may be wasted, if lesser number of elements are used i.e. if entire array is not utilized.The list cant grow in its size beyond the size of the declared array, if required, during the program execution. Thus, in some cases, when a program is executing the memory space wont be enough to work with the actual number of elements.

Operations such as insertion and deletion of an item at a certain location in a list involve a lot of data movement.

All the above operations finally lead to inefficient use of memory.

Also these operations require time-consuming algorithms.

The advantages of Linked lists over arrays are,

The list can grow and shrink in size during program execution. Thus the maximum limit on the size of the list will not be a problem while adding and inserting items in the list. Thus, an exact amount of memory space is utilized by the List. Wastage of extra memory or shortage of memory will not occur.

Insertion and deletion of a list item does not involve movement of data. Drawbacks: The place (node) at which these operations are done in the list are not directly accessible like in arrays where using an array index programmer can access any item in the list directly.

Secondly, every element holds a link field within it, taking extra memory.ADT (Abstract Data Type):

Data abstraction basically implies hiding data from user.

Abstract Data Type can be defined as a package of Data declaration and the operations that are meaningful on the data.

ADT mentions what operations can be performed on the data. But exactly how the operations are performed is hidden from user of the data.

Thus, ADT is a useful tool for specifying logical properties of a data type(Or a

particular concept that a programmer want to implement). While defining an ADT we are not concerned with the time or space efficiency of the functionalities.

Also, ADT is not concerned with how a particular function is implemented. It just explains what different operations are possible with the data type.

Linked List ADT:

Data: Linked list holds multiple elements that are Nodes. Each node holds one information and link to at least one (mostly a link to next node ) other node in the list.

Oparations:

Add : Adding a new node to the list.

Remove: Removing a node from the linked list.

Insert : Insert a new node at the given positioning the list.

Display: Displaying the information the nodes of the linked list.

Circular Linked List:

The operations on circular linked list and their algorithms are follows.

A structure for a node of a list will be is same as that discussed in singly linked list. The reference variables root and last will be also required.

Adding a node:

An algorithm for adding a node to the circular linked list is same as that for simple linked list (See algorithm A-1 for linear linked list). One difference is that the link in a newly allocated node will hold reference for the first node in the list. Thus, in the algorithm add new step at the end as follows,

Put root pointer in new nodes link.

Displaying nodes in the linked list:

Algorithm for displaying the list contents is as follows,

A 51. Read the root pointer2. Repeat following

i.Display contents of node referred by the pointer

ii.Update pointer to the next node

iii. Repeat 2.i , 2.ii till the pointer is not root pointer. Removing a node from a list:

There are three cases in removing a node from a list.

1. Removing a first node: 2. Removing a last node: 3. Removing any other node:A-6

1.Read the value of node to be deleted

2.Read the root node pointer

3.Repeat following steps

a.If the pointer refers to the Node to be deleted then

stop the search

b. Else

Update pointer to refer to next node

c. If root node is not reached then go to step 3.a

4. If required node is found in step 3 then

i.If it is first node

Update root of list to refer to second node

Update the link in the last node to new root

ii. Else if its a last node

Update link in a second last node to root pointer

iii.Else

Put pointer of next node in the previous node

iv.De-allocate the deleted node

5. If node not found print message

Inserting a node (before given node) :

An algorithm to insert an item in the list is as follows,

A-7

1. Input the value of node where new node is to be inserted

2. Input value for new node

3.Read the root pointer

4.Repeat following steps

a. If the pointer refers to the node where a new node is to be inserted then

i. stop search

b. Else

Update pointer to refer to next node.

c. If pointer dont refer to root, go to 4.a

5. If required node is found in step 4

a.Allocate memory for new node

b.Put the value in the new node

c.Store pointer for current node in the new node

c.If current node is first node

Update root to refer to a new node.

Update pointer in the last node to refer to the new node.(new root)

d. Else

Update link in the previous node to refer to a new node

6. If node not found print message

Program for Circular linked list#include

#include

#include

struct Node{

int data;

struct Node *next;

};

struct Node *root=NULL, *last=NULL;

// Function prototypes for ADT

void CreateList( int n );

void Display( void );

void InsertBefore( int p, int v);

void InsertAfter( int p, int V);

void DeleteNode(int p);// Functions for Circular linked list

void CreateList( int n )

{

int i, v;

Node *nw;

// Create a root node

printf("Enter a node value:");

scanf("%d", &v);

root = (struct Node*) malloc( sizeof(struct Node) );

root->data = v;

root->next = root;

last = root;

// Create remaining n-1 nodes

for( i=1; idata = v;

nw->next = root;

last->next = nw;

last = nw;

}

}

void Display()

{

struct Node *r;

if( root == NULL )

printf("List is empty\n");

else

{

r = root;

printf("Nodes...\n");

do

{

printf("%d\t", r->data);

r = r->next;

} while( r!= root );

printf("\n");

}

}

void InsertBefore( int p, int v)

{

struct Node *cur, *prev, *nw;

int found = 0;

cur = root;

do

{

if( cur -> data == p )

{

found = 1;

break;

}

else

{

prev = cur;

cur = cur->next;

}

}while( cur != root );

if( found )

{

nw = (struct Node*) malloc( sizeof( struct Node) );

nw->data = v;

if( cur == root )

{

nw->next = root;

root = nw;

last->next = root;

}

else

{

prev->next = nw;

nw->next = cur;

}

}

}

void InsertAfter( int p, int v)

{

struct Node *cur,*nxt, *nw;

int found =0;

cur = root;

do

{

if( cur -> data == p )

{

found=1;

break;

}

else

cur = cur->next;

}while( cur != root );

if( found )

{

nw = (struct Node*) malloc( sizeof( struct Node) );

nw->data = v;

if( cur->next == root )

{

cur->next = nw;

nw->next = root;

last = nw;

}

else

{

nxt = cur->next;

cur->next = nw;

nw->next = nxt;

}

}

}

void DeleteNode( int p )

{

struct Node *cur, *prev;

int found=0;

cur = root;

do

{

if( cur -> data == p )

{

found = 1;

break;

}

else

{

prev = cur;

cur = cur->next;

}

}while( cur != root );

if( found )

{

if( cur == root )

{

root = root->next;

last->next = root;

}

else if( cur->next == root )

{

prev->next = root;

last = prev;

}

else

{

prev->next = cur->next;

}

free( cur );

}

}Note : main() function will be same as that of singly linked list. Refer to program written in class.

Doubly Linked list :

Since each node holds link for next and previous nodes, the node structure is defined with two node pointers. ( refer to Doubly linked list program )

Adding a node to the list:

Algorithm for adding a new node to a doubly linked list is given below.

A-8

1.Input the value to be stored in a new node.

2Allocate memory for new node

3.Store the value in information part and null in both the pointers in the new node.

4.If the list is empty

Store reference for the node in root poiter

6.Else

Put pointer of the new node in the forward link of last node.

Put pointer for the last node in the backward link of the new node.

7.Put pointer for a new node in last pointer.

Displaying linked list nodes:

Refer to Display algorithm of Singly linked list.Removing a node:

Algorithm to remove an item from the list,

A- 9

1. Read the value of the node to be removed

2. Read the root pointer

3.While not end of a list do ..

a. If value found in current node

Stop the search

b. Else

Update pointer to refer to next node

4. If required node is found in step 3 then

i.If it is root node of list

Update root of list to refer to second node

Put null in the backward link of new root node

ii.Else if its a last node

Update forward link of second last node to null

Update the last pointer to refer to the second last node.

iii.Else

Update forward link in previous node to refer to next node

Update backward link in next node to refer to previous node

iv. Stop the loop

5.If node not fond display message.

Inserting a Node (before given node) :

An algorithm to insert a node in the list is as follows,

A- 10

1. Input the value of the node (key) where new node will be inserted.

2. input a new data for a new node to insert.

3. Read the root pointer

4. While not end of a list do ..

a. If key found in current node

Stop the search

b. Else

Update the pointer to refer to next node

4. If key is found in step 4 then,

i.Allocate memory for new node

ii.Store value in new node and put the links for previous and current

nodes in the new node.

iii.If new node to be inserted at the beginning

Update backward link of the root node the new node pointer.

Update root pointer to refer to the new node

iv.Else

Update Forward link of previous node to refer to new node

Update Backward link of current node to refer to new nodeb. If node not found then display error message.

Program for Doubly Linked list:

#include

#include

#include

struct Node{

int data;

struct Node *prev, *next;

};

struct Node *root=NULL, *last=NULL;

void CreateList( int n );

void Display( void );

void InsertBefore( int p, int v);

void InsertAfter( int p, int V);

void DeleteNode(int p);void CreateList( int n )

{

int i, v;

Node *nw;

// Create a root node

printf("Enter a node value:");

scanf("%d", &v);

root = (struct Node*) malloc( sizeof(struct Node) );

root->data = v;

root->next = root->prev = NULL;

last = root;

// Create remaining n-1 nodes

for( i=1; idata = v;

nw->next = NULL;

nw->prev = last;

last->next = nw;

last = nw;

}

}

void Display()

{

struct Node *r;

if( root == NULL )

printf("List is empty\n");

else

{

r = root;

printf("Nodes...\n");

while( r != NULL )

{

printf("%d\t", r->data);

r = r->next;

}

printf("\n");

}

}

void InsertBefore( int p, int v)

{

struct Node *cur, *pr, *nw;

int found = 0;

cur = root;

while( cur != NULL )

{

if( cur -> data == p )

{

found = 1;

break;

}

else

{

pr = cur;

cur = cur->next;

}

}

if( found )

{

nw = (struct Node*) malloc( sizeof( struct Node) );

nw->data = v;

if( cur == root )

{

nw->next = root;

nw->prev = NULL;

root = nw;

}

else

{

pr->next = nw;

nw->prev = pr;

nw->next = cur;

cur->prev = nw;

}

}}

void InsertAfter( int p, int v)

{

struct Node *cur,*nxt, *nw;

int found = 0;

cur = root;

while( cur != NULL )

{

if( cur -> data == p )

{

found = 1;

break;

}

else

cur = cur->next;

}

if( found )

{

nw = (struct Node*) malloc( sizeof( struct Node) );

nw->data = v;

if( cur->next == NULL )

{

cur->next = nw;

nw->prev = cur;

nw->next = NULL;

last = nw;

}

else

{

nxt = cur->next;

cur->next = nw;

nw->prev = cur;

nw->next = nxt;

}

}

}

void DeleteNode( int p )

{

struct Node *cur, *pr, *nxt;

int found =0;

cur = root;

while( cur != NULL )

{

if( cur -> data == p )

{

found =1;

break;

}

else

{

pr = cur;

cur = cur->next;

}

}

if( found )

{

if( cur == root )

{

root = root->next;

root->prev= NULL;

}

else if( cur->next == NULL )

{

pr->next = NULL;

last = pr;

}

else

{

nxt = cur->next;

pr->next = nxt;

nxt->prev = pr;

}

free( cur );

}}Linked List using Array :

In this implementation of list an array is used to hold elements i.e. Nodes of linked list.Each element of the array holds data and link for the next element (i.e. Node) in the list. Links are the array indexes.

Last element of the list holds -1 as index to indicate end of list.

Deleting and inserting nodes requires updating the links i.e. array indexes properly.

This requires a bit complex coding.

No pointers and dynamic memory allocations.

Drawback is that the Size of the list is limited to array size. And fixed amount memory will be used whatever number of nodes are really present.

Following figure shows linked list with four elements (10,20,30,40). Array size is Six. Next variable in each node holds link for (index of) the next element in the list.datanext

0101

1202

2303

3404

45

5-1

Program for Linked list using Array is given below :#include

#include

#include

#define Size 6

struct Node

{

int data;

int next; // holds array-index of next node in the list};

// Global variables to maintain list.

struct Node A[Size]; // Array to hold Nodes i.e. linked listint first, avail, last;

void Initialize( )

{

int i;

first = last = -1; // index of first and last item in the list.

avail= 0; // index of next available element.

for(i=0; i< Size -1 ; i++) // Initialize all the nodes to hold next index

{

A[i].next = i+1; // link each element of array to next

}

A[ Size-1].next = -1 ; // next= -1 indicates last item

}

int GetNode()

{

int p;

p = avail;

avail = A[avail].next;

if(first== -1) // if list is empty.. first element is root

first=0;

return p;

}

void AddNode(int v)

{

int p;

p = GetNode();

A[p].data = v;

last = p;

}

void InsertAfter(int pos, int val)

{

int p;

if(pos == -1 || pos == avail)

printf("\n Invaliid position ...\n");

else if(pos == last)

AddNode(val);

else

{

p = GetNode();

A[p].data = val;

A[p].next = A[pos].next;

A[pos].next = p;

A[last].next = avail;

}

}

void FreeNode(int p)

{

if( p == first )

{

first = A[p].next;

}

A[p].next =avail;

avail = p;

}

int DeleteNode(int pos)

{

int cur=first, prev=-1;

int v; // to store value at given pos.

while(cur != pos)

{

prev = cur;

cur = A[cur].next;

}

v = A[pos].data;

A[prev].next = A[pos].next;

FreeNode(pos);

A[last].next = avail;

return(v);

}

void Display()

{

int r=first;

if( r != -1)

{

printf("\nList elements...\n");

while( r != avail)

{

printf("%d\t", A[r].data );

r = A[r].next;

}

}

else

{

printf("\nList is empty ...\n");

}

}

void main()

{

int d;

char a,ch;

int cno;

clrscr();

Initialize();

printf(" -- Linked list [Array implementation]--\n");

while ( 1 ) // always true

{

printf("\n\n== MAIN MENU ==\n");

printf("\nAdd - a\n");

printf("Show list - s\n");

printf("Remove - r\n");

printf("Insert - i\n");

printf("Quit - q\n\n");

printf("Your choice:");

scanf("%c", &ch);

printf("\n\n");

switch(tolower(ch))

{

case 'a':

while(1)

{

printf("Enter no:");

scanf("%d",&d);

fflush(stdin);

AddNode(d);

printf("Press 'y' to continue...");

scanf("%c", &a);

fflush(stdin);

if(tolower(a) != 'y' )

break;

}

break;

case 's' : Display();

break;

case 'i' :

printf("\nInsert after what pos :");

scanf("%d",&cno);

printf("Enter new num :");

scanf("%d",&d);

fflush(stdin);

InsertAfter(cno, d);

break;

case 'r':

printf("\nWhich node to remove .. enter pos:");

scanf("%d",&cno);

d = DeleteNode(cno);

printf("Info. in del. node:%d\n", d);

break;

case 'q':

return;

default:

printf("Invalid choice...\n");

}

}

getch();

}

Some additional functions on Linked lists:

1. Displaying singly linked list (Recursive function):

void displayRec(struct Node *r)

{

if( r != NULL )

{

printf(%d\t, r->data);

displayRec( r->next ); // recursive call with new link

}

}The above function is called with root node of the list i.e. link for the first node as a parameter.

e.g. displayRec ( root );

2. Recursive function to print Singly linked list in Reverse order:

void displayRev(struct Node * r)

{

if( r != NULL )

{

displayRev( r->next ); // recursive call with new link

}

printf(%d\t , r->data);

}

The above function is called with root node of the list i.e. link for the first node as a parameter.

e.g. displayRev (root ); 3. Comparing two linked lists:

The function compares the linked lists passed as arguments. Return 1 if they have same values in all nodes and lengths are also same. Function parameters are root pointers of the lists to be compared.

int equals( struct Node *r1, struct Node *r2 )

{

int v = 1;

if( r1== NULL && r2 == NULL )

return 1;

else

{

while( r1 != NULL )

{

if( r2 == NULL )

{

v = 0;

break;

}

if( r1->data != r2->data )

{

V = 0;

break;

}

r1 = r1->next;

r2 = r2->next;

}

if( r1 != NULL || r2 != NULL )

v= 0;

}

return v;

}4. Creating a Sorted Linked list:

The sorted linked stores nodes in the ascending order of values of the nodes. i.e. Node with the smallest value will be the first element of the list and that with the largest value will be the last node of the list.

Following function inserts a new node at the proper position in the list so that the list nodes are in the ascending order. If the new node has smallest value it will be inserted as a root node and a node value is larger than the other nodes the new node is added at the end of list. ( Assume singly linked list)

void createSortedList(int val)

{

struct Node *cur=NULL, *prev=NULL, *nw;

nw = malloc(sizeof(struct Node));

nw->data = val;

nw->next = NULL;

if(root==NULL) // if list is empty

{

root=nw;

last=nw;

}

else if( val > last->data) // if value is greater than last node value

{

last->next =nw;

last = nw;

}

else

{

cur=root;

while(cur->data < val) // move in the list to get proper position

{

prev=cur;

cur=cur->next;

}

if(cur==root) // to insert node at beginning

{

nw->next = root;

root=nw;

}

else // insert node at any other position

{

prev->next = nw;

nw->next = cur;

}

}

}

5. Reversing a singly Linked list without any additional node allocations:

Assume root and last are the links for first and last nodes of a linked list.

void reverse(){

if( root != NULL )

{

struct Node * cur, *prev= NULL , *nxt= NULL, *t;

cur = root;

while( cur != NULL )

{

nxt = cur->next;

cur->next = prev;

prev =cur;

cur =nxt;

}

t=root;

root=last;

last=t;

}

}

Data Link

Node

D

A

B

C

D

C

D

These notes are also available at :

www.santoshkabirsir.com

Email : [email protected]

Visit : www.santoshkabirsir.com

( for batch timetables, QP soln etc. )

Classes for Engg. students:

FE SPA Sem II

SE DS (Comp) , DSAA ( IT ) Sem III

OOPM (Java) ( Comp, IT)Sem III

Web Programming. (IT ) Sem IV

(JSP, C#, ASP.Net, PHP etc)

* With practicals *

By Santosh Kabir sir.

Contact: 98336 29398

Andheri, Dadar, Thane

C

B

A

B

A

Fig. 1

=====000000=====

Notes prepared by: Santosh Kabir

1.Linked ListsMobile : 98336 2939823 of 23www.santoshkabirsir.com