0% found this document useful (0 votes)
21 views34 pages

DS - Module 2,3 (LinkedLists)

DS - 3RDSEM MODULE 2,3
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views34 pages

DS - Module 2,3 (LinkedLists)

DS - 3RDSEM MODULE 2,3
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

MODULE 2,3: LINKED LISTS

1. Disadvantages of Arrays:
a. The size is fixed.
It is not possible to predict the exact size of the memory required in the program.

b. The elements are stored continuously next to each other.


There may come a situation where there is availability of a number of chunks of
contiguous memory locations whose size my not be sufficient to store the items
and hence leads to the wastage of storage space.

c. Insertion and deletion operatios is a tedious task.


If insertion needs to be done in the ith position, then all the elements from (i+1)th
position have to be moved to the next subsequent locations.
Similarly, when deletion needs to be done from the ith position, all elements from
(I +1)th position should be moved to their corresponding previous locations.
This results in extensive manipulation of stored data and more time is spent in just
moving this data.
This can be overcome using linked lists.

2. Definition: Linked list is a non-sequential collection of nodes. Each node has 2 fields
namely,
i. Info field, which stores the data or information to be manipulated.
ii. Next/ link field, contains the address of the next node.

Info link

Address of next node


3. Classification of linked lists:
It can be classified into 4 types namely,
i. Singly linked list
ii. Doubly linked list
iii. Circular singly linked list
iv. Circular doubly linked list

4. Representation of Linked lists:


 List is represented in two linear arrays namely, INFO and LINK where INFO
contains the information part and LINK contains the address of the next node.
 Also, it contains a variable name START, which contains the location of the
beginning of the list.
 The nodes of the list need not occupy adjacent elements in the arrays INFO and
LINK.
 Linear arrays INFO and LINK may contain more than one list, where each list
have a pointer variable giving the location of its first node.

Example:
A) Singly Linked List(SLL):
This is called SLL because, this list consists of only one link, to point to next node.

2004 1020 5012


11 1020 12 5012 13 NULL

INFO LINK INFO LINK INFO LINK

2004

 The last field of the last node is NULL, indicating that there are no further nodes.
 Initially, when no nodes are created, the variable first will contain NULL, indicating that
the linked list does not exist.
Operations performed on SLL:
1. Create a node(How to define a node?)
Struct node // structure definition of a node
{
Int INFO;
Struct node *link;
}
Struct node // structure definition of node along with declaration of a variable
{
Int INFO;
Struct node *link;
};
Typedef struct node *NODE;
//Creating an empty list
First = NULL;
// Creating a new node
MALLOC(first, 1, struct node);
// store the data
First->info = 10;
First->link = NULL;

First->info first->link
10 NULL

First

2. Insertion at the beginning

Steps:
i. Allocate memory for the new node temp

ii. Copy the item into ‘info’ field of temp.


iii. Copy the address of the first node of the list in the ‘link’ field of temp.

iv. Return the address of the first node temp.

Code:
Insert_front()
{
NODE temp;
MALLOC(temp, 1, struct node); //obtain a node from the available list
Temp->info = item; // insert an item into new node
Temp->link = first; // insert new node at the front of the list
Return temp; // return the new first node
}

3. Insertion at the end

Steps:
a) Create a new node temp.

b) If the list is empty, the new node temp is returned as the first node.

c) If the list is not empty, then the new node is inserted at end of the list.(For
this, we need to obtain the address of the last node. So, we have to start from
the first node using a variable ‘cur’ which initially points to the first node.)
d) Obtain the address of the last node.

e) The new node temp is linked to the link field of the cur.

NODE insert_rear(int item, NODE first)


{
NODE temp; // points to newly created node.
NODE cur; // to hold the address of the last node.
MALLOC(temp, 1, struct node); //obtain the new node and copy the item
Temp->info = item;
Temp->link = NULL; // step 1

If(first == NULL) return temp; // step 2

Cur = first; // steps 3 and 4


While(cur->link!= NULL);
{
Cur cur->link;
}
Cur->link = temp; // step 5
Return first; // step 6
}

4. Display

Steps:
a) Check if the list is empty. If empty, display List is empty.

b) If list is existing, make temp contain the address of the first node and display
temp and continue with the rest nodes using their corresponding links.

Void display()
{
NODE temp;
If(first = = NULL) // step a
{
Printf(“List is empty\n”);
Return;
}
Printf(“\n The contents of singly linked list”); // step b
Temp = first;
While(temp ! = NULL)
{
Printf(“%d”, temp->info);
Temp = temp->link;
}
Print(“\n”);

5. Delete a node at the beginning

Steps:
i. Check if the list is empty.

ii. If list is existing, then make the temp store the address of the first node.

iii. Update the temp variable to hold the address of the second node.

iv. Initially, ‘first’ variable points to the first node of the list and now variable
‘temp’ is made to point to second node of the list. So, using the variable
‘first’, the first node can be deleted.
Delete_front()
{
NODE temp;
If( first == NULL) // step i
{
Printf(“List is empty, cannot delete\n”);
Return first;
}
Temp = first; //retain address of the node to be deleted.
Temp = temp->link; // obtain address of the second node.
Printf(“Item deleted = %d\n”, first->info);
Free(first); // delete the front node
Return temp; // return the address of the first node.
}
6. Delete a node at the end

Steps:
1. Check if the list is empty.

2. Check for the list if it contains only one node, if so, it can be deleted using
free().

3. If the list contains more than one node, obtain the address of the last node and
just previous to that.
4. To delete the last node pointed by cur, free() function is used.

5. Once, the last node is deleted, the node pointed by prev should be the last
node.

6. Return the address of the first node.

Delete_rear()
{
NODE cur, prev;
If(first == NULL) // step 1
{
Printf(“List is empty cannot delete\n”);
Return first;
}
If(first->link == NULL) // step 2
{
Printf(“The item to deleted is %d\n”, first->info);
Free(first);
Return NULL;
}

Cur = first;
While(cur->link ! = NULL)
{
Prev = cur;
Cur = cur->link;
}
Printf(“The item deleted is %d\n”, cur->info); // step 4
Free(cur);
Prev->link = NULL; // step 5
Return first; // step 6
}
1. Traversing the list: It is a process of visiting each element of the list only once. (Visiting
each element may involve processing the each element where in, the process may be to
find the length of the list, search an item in in the list, delete a specified node in the list,
concatenate two lists, etc….
1. Length of the list
Int Length(NODE first)
{
NODE cur;
Int count = 0;

If(first == NULL) return 0; // check for empty list


Cur = first; // as long as no end of the list
While (cur != NULL)
{
Count++; // update count by 1
Cur = cur->link; // point cur to the next node
}
Return count; // return the length of list

2. Search an item in the list

Void search(int key, NODE first)


{
NODE cur;

If(first = = NULL) // check for empty list


{
Printf(“list is empty\n”);
Return;
}

//compare one after the other


Cur = first;
While(cur!= NULL) /. As long as no end of list
{
If(key == cur->info) break; // if item found, go out of loop
Cur = cur->link; // point cur to next node
}

If( cur == NULL)


{
Prinft(“Search is unsuccessful\n”);
Return;
}
Printf(“Search is successful\n”);
}

3. Delete a specified node from the list

Steps:
1. Check for empty list

If(first == NULL)
{
Printf(“List is empty\n”);
Return;
}

2. Check if key is present in the first node. If so, delete the first node

Code:
If( key = = first->info)
{
Cur =first; // save the address of the first node.
First = first-> link; // update first to point to next node.
Free(cur); // Delete the first node pointed to by cur.
Return first; // return the address of the first node.
}

3. If key is not the first node, then check with subsequent nodes

Code:
Prev = NULL;
Cur = first;
While(cur != NULL) // as long as no end of list
{
If(key = = cur->info) break; // if found, go out of loop
Prev = cur; // save the address of cur node
Cur = cur->link; // point cur to the next node
}
If(cur == NULL) // if end of the list, key not found
{
Printf(“Search is unsuccessful\n”);
Return first;
}
Printf(“Search is successful”);

4. Keep updating ‘cur’ and ‘prev’ as long as key is not equal to info of cur.
Once the key is found, cur has the address of the node to deleted and prev
has the address of its predecessor as shown below;

Prev->link = cur->link;

5. The node pointed by cur is deleted using free()

Free(cur);

6. Return the address of the first node.


Return first;

4. Concatenate two lists


Joining the second list at the end of the first list. It is possible if two lists exists. If
one of the list is empty, return the address of the first node of the non-empty list.
If ( first == NULL) return second;
If( second == NULL) return first;

If both lists exist, obtain the address of the last node of the first list by,
Cur = first;
While(cur->link!=NULL)
Cur = cur->link;// cur has the address of the last node of first list.

Now, attach the address of the first node of the second list to cur node by,
Cur->link = second;
Next, return the first list.
Return first;

A.1 Circular singly linked list: Circular list is a variation of linked list in which link field of the
last node contains the address of the first node. This is represented as shown below,

Since the list is circular, any node can be considered as first node and its predecessor is
considered as last node. There are two cases:
Case 1: Variable ‘first’ can be used to designate the starting point of the list. Here, to get
the address of the last node, entire list has to be traversed.
Case 2: Variable ‘last’ can be used to designate the last node and the node that follow last
can be designated as the first node.
Operations performed on circular singly linked list(CSLL):
1. Insert_front()

Steps:
1. Obtain a free node using malloc.
2. Copy the address of the first node into the link field of new node.
3. Establish a link between new node temp and the last node.
4. Finally, return the address of the last node.

Code:
NODE insert_front(int item, NODE last)
{
NODE temp;

MALLOC(temp, 1, struct node); // create a new node to be inserted


Temp->info = item;

If(last == NULL) // make temp as the first node


Last = temp;
Else
Temp->link = last->link; // insert at the front end
Last->link = temp; //link last node to first node

Return last; // return the last node.


}

2. Insert_rear()
Steps:
1. Obtain a new node using malloc.
2. Copy the address of first node to the link field of new node.
3. Establish the link between new node temp and the last node.
4. The new node is made as the last node.
Code:
NODE insert_rear(int item, NODE last)
{
NODE temp;

MALLOC(temp, 1, struct node); // create a new node to be inserted


Temp->info = item;

If(last = = NULL) // make temp as the first node


Last = temp;
Else
Temp->link = last->link; // insert at the rear end
Last->link = temp; // link last node to first node
Return temp; //make the new node as the last node
}

3. Delete_front()
Steps:
i. Obtain the address of the first node.
ii. Link the last node and the new first node.
iii. Delete the old first node.
Code:

NODE delete_front(NODE last)


{
NODE temp, first;

If( last == NULL) // check for empty list


{
Printf(“\n list is empty”);
Return NULL;
}

If( last->link == last) // delete if only one node


{
Printf(“The item deleted is %d\n”, last->info);
Free(last);
Return NULL;
}

// if list contains more than one node


First = last->link; // obtain node to beleted
Last->link = first-> link; // store the new first node in the link of last node
Printf(“\n Item deleted is %d”, first->info);
Free(first); // delete the old first node
Return last; // return the address of the last node.
}

4. Delete_rear()
Steps:
1. Obtain the address of the predecessor of the node to be deleted.
2. Link the first node and last but one node.
3. Delete the last node.
4. Return prev itself as the last node.

Code:

NODE delete_rear(NODE last)


{

If(last == NULL) // check if list is empty


{
Printf(“\n list is empty”);
Return NULL;
}

If(last->link == last) // delete if only one node


{
Printf(“\n item deleted is %d”, last->info);
Free(last);
Return NULL;
}

// if more than one node exists


Prev = last->link; // obtain the address of the previous node
While(prev->link ! = last)
{
Prev = pre->link;
}
Prev->link = last->link; // prev node is made the last node
Printf(“the item deleted is %d\n”, last->info);
Free(last); // delete the old last node
Return prev; //return the new last node
}
5. Display()

Code:

Void display(NODE last)


{
NODE temp;

If(last == NULL) // check for empty list


{
Printf(“list is empty\n”);
Return;
}

// Display till we get the last node


Printf(“\n contents of the list are: “);

Temp = last_link;
While(temp!= last)
{
Printf(“%d”, temp->info);
Temp = temp->link;
}
Printf(“%d”, temp->info);
}

B) Header Node
A header node in a linked list is a special node whose link fields always contains the
address of the first node of the list. If the list is empty, then link field of the header node
contains \0 (NULL).

Circular list with header node


 In a circular list with a header node, the link field of the last node contains the
address of the header node and the link field of the header node contains the address
of the first node.
 The info field of the header node may not contain any data or it may contain the
information about total number of nodes present in the list. When the list is empty,
the link field of the header node contains the address of itself.
Example:

Operations performed on header node:


1. Insert a node at the front end

Code:

NODE insert_front(int item, NODE head)


{
NODE temp;
MALLOC(temp, 1, struct node); //create a node and insert the item
Temp->info = item;

Temp->link = head->link; // Establish a link between the newly created


temp and the first node.

Head->link = temp; // the newly created temp is made first node by creating
a link between the header node and temp
Return head; // return the address of the header node.

2. Insert a node at the rear end

Code

NODE insert_rear(int item, NODE head)


{
NODE temp, cur;

MALLOC(temp, 1 , struct node); //Create the node to be inserted


Temp->info = item;

Cur = head->link; // obtain the address of the last node


While(cur->link != head)
{
Cur = cur->link;
}

Cur->link = temp; // insert temp at the end


Temp->link = head;

Return head; // return the address of the header


}

3. Display
Code

Void display(NODE head)


{
NODE temp;

If(head->link = = head) // check for empty list


{
Printf(“list is empty\n”);
Return;
}

Printf(“\n the contents of singly linked list”);

Temp = head->link; // holds the address of first node


While(temp!=head) // as long as no end of list
{
Printf(“%d”, temp->info); // display the info field of node
Temp = temp->link; // point to the next node
}
Printf(“\n”);
}

C) Doubly Linked List(DDL):


1. Definition: It is a collection of node where each node consists of 3 nodes,
Info – where the information has to be stored.
Next – contains the address of the next node.
Prev – contains the address of the previous node.
Circular doubly linked list:
A circular doubly linked list is a variation of doubly linked list in which,
 rlink of the last node contains the address of the first node and
 Llink of the first node contain the address of the last node.
It is pictorially represented as shown below,

Circular doubly linked list with header


It is a variation of doubly linked list with a header node in which,
 Llink of header contains address of the last node of the list.
 Rlink of the header contains the address of the first node of the list.
 Llink of last node contains the address of last but one node of the list.
 Rlink of last node contains the address of the header node of the list.
Pictorial representation is as shown below,
Operations performed on Doubly linked list:
1. Insert a node at front end

NODE insert_front(int item, NODE head)


{
NODE temp, cur;

MALLOC(temp, 1, struct node); // node to be inserted


Temp->info = item;

Cur = head->rlink; // obtain the address of first node

Head->rlink = temp; // insert between header and first node


Temp->llink = head;
Temp->rlink = cur;
Cur->llink = temp;

Return head; // return the header node


}

2. Insert a node at rear end


NODE insert_rear(int item, NODE head)
{
NODE temp, cur;

MALLOC(temp, 1, struct node); // node to be inserted


Temp->info = item;

Cur = head->llink; // obtain address of the last node

Head->llink = temp; // insert at the end of the list


Temp->rlink = head;
Temp->llink = cur;
Cur->rlink = temp;

Return head; // return the address of header node

3. Delete a node from the front

Code
NODE delete_front(NODE head)
{
NODE cur, next;
If(head->rlink = = head) // check for empty list
{
Printf(“List is empty”);
Return head;
}
Cur = head->rlink; // obtain the first node
Next = cur->rlink; // obtain the second node
Head->rlink =next; // adjust pointers and delete the node
Next->llink = head;
Printf(“The node to be deleted is %d\n”, cur->info);
Free(cur); // delete the first node
Return head;
}

4. Delete a node from the rear end

Code
NODE delete_rear(NODE head)
{
NODE cur, prev;
If(head->llink == head)
{
Printf(“\n list is empty”);
Return head;
}
Cur = head->llink; // obtain the address of the last and last but one node
Prev = cur->llink;
Head->llink = prev; // adjust links in both directions
Prev->rlink = head;
Printf(“\n The node to be deleted is %d”, cur->info);
Free(cur); // delete the node
Return head;
}

5. Insert a node after a key and before a key


a) NODE insert_right( int item, NODE head)
{
NODE temp, cur, next;
If(head->rlink == head) //check for empty list
{
Printf(“\n List is empty”);
Return head;
}
Cur = head->rlink; //search for the key
While(cur != head)
{
If(item == cur->info) break;
Cur = cur->rlink;
}
If(cur == head)
{
Printf(“\n key not found”);
Return head;
}
/ a node with key is found
Next = cur->rlink; // obtain the address of successor node
Printf(“Insert the item to insert towards right of %d = “, item);
MALLOC(temp, 1, struct node);
Scanf(“%d”, &temp->info);

Cur->rlink = temp; // insert this new node between cur and next
Temp->llink = cur;
Next->llink = temp;
Temp->rlink = next;

Return head;
}

b) NODE insert_left(int item, NODE head)


{
NODE temp, cur, prev;
If(head->rlink = = head) // check for empty list
{
Printf(“List is empty”);
Return head;
}

Cur = head->rlink; // search for the key


While(cur! = head)
{
If(item == cur->info) break;
Cur = cur->rlink;
}
If(cur == head)
{
Printf(“\n key not found”);
Return head;
}
// a node with key is found
Prev = cur->llink; // obtain the predecessor
Printf(“Enter the item to insert towards left of %d = “, item);
MALLOC(temp, 1, struct node);
Scanf(“%d”, &temp->info);

Prev->rlink = temp; // insert between prev and cur


Temp->llink = prev;
Cur->llink = temp;
Temp->rlink = cur;
Return head; // return address of the header
}

D) Polynomials
Polynomials can be represented using linked lists in C. In this representation, each term
of a polynomial representing coeff and expon can be stored in a node along with a pointer
to the next term. A node can be declared as shown below,

Struct node
{
Int coeff; // coefficient of the term
Int expon; // power of x in the term
Struct node *link; // points to the next term
};
Typedef struct node *NODE;
NODE a, b; //a holds the first polynomial and b holds the second polynomial

A(x) = am-1 xem-1 + … + a0 xe0


Example:
The polynomials a = 3x14 + 2x8 + 1 and b = 8x14 – 3x10 +10x6

1. Adding polynomials
Steps:
a) Check whether the exponents of the terms of both polynomials a and b are equal.

b) If the exponents of two terms are equal, then add the two coefficients and create a
new term for the result. Also, move the pointers to the next nodes in a and b.
c) If the exponent of the current term in a is less than the exponent of the current term
in b, then create a duplicate term of b, attach this term to the result called c, and
advance the pointer to the next term in b.

d) If the exponent of the current term in a is greater than that of b, then create a
duplicate of a and attach this term to result called c and advance the pointer to the
next term in a.
Padd code:

polyPointer padd(polyPointer a, polyPointer b)


{
// return the polyPointer which is the sum of a and b
polyPointer c, rear, temp;
int sum;
MALLOC(rear, sizeof(*rear));
C = rear;
While (a && b)
Switch(COMPARE(a->expon, b->expon))
{
Case -1: //a->expon < b->expon
Attach(b->coef, b->expon, &rear);
B = b->link;
Break;
Case 0: // a_expon = b->expon
Sum = a->coef + b->coef;
If(sum) attach(sum, a->expon, &rear);
A = a->link; b = b->link; break;
Case 1: //a->expon > b->expon
Attach(a->coef, a->expon,&rear);
A = a->link;
}
//copy rest of list a and then list b
For(; a; a = a->link) attach(a->coef, a->expon, &rear);
For(; b; b = b->link) attach(b->coef, b->expon, &rear);
Rear->link = NULL;
//delete extra initial node
Temp =c; c = c->link; free(temp);
Return c;
}

2. Erasing polynomials
If we wish to use more polynomials, then we can always reuse our temp variable used to
hold partial results by returning the nodes of temp and use them to hold other
polynomials.

Code:
Void erase(polyPointer *ptr)
{
//erase the polynomial pointed by ptr
polyPointer temp;
while(*ptr)
{
temp = *ptr;
*ptr = (*ptr)->link;
Free(temp);
}
}

You might also like