DS - Module 2,3 (LinkedLists)
DS - Module 2,3 (LinkedLists)
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.
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
Example:
A) Singly Linked List(SLL):
This is called SLL because, this list consists of only one link, to point to next node.
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
Steps:
i. Allocate memory for the new 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
}
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.
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”);
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.
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;
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;
Free(cur);
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;
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;
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:
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:
Code:
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).
Code:
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.
Code
3. Display
Code
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;
}
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;
}
Cur->rlink = temp; // insert this new node between cur and next
Temp->llink = cur;
Next->llink = temp;
Temp->rlink = next;
Return head;
}
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
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:
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);
}
}