DSshortnotes Module3 1
DSshortnotes Module3 1
DSshortnotes Module3 1
Module III
Linked List:
other.
Whenever there is a need to add a new element to the list, a new node is created
and appended at the end of the list.
An array is allocated fixed amount of memory space before a program is
executed.
Thus, if there is a need at run time to store more data in the array than its
actual capacity, then there is no way of doing this.
The linked list allows for dynamic allocation of memory space at runtime.
Thus, there is no need to block memory space at compile time.
Linked list is not constrained to be stored in adjacent memory locations as in
array.
Definition:
Linked list is a collection of nodes stored in such a manner that each node points
at the next node in the list.
Each node has two parts: data part and link part.
The data part contains the data element while the link part contains the address of
the next node.
The implementation of linked list in C programming language, using structure can
be defined as
struct node
{
int data;
struct node *link;
};
The link is a pointer that contains the address to indicate the location of the
successor node. The link part of the last node of the list contains a NULL value
indicating the end of the list. The address of the first node in the list is indicated
by the pointer p.
p
1000
Doubly linked list - Doubly linked list is a complex type of linked list in
which a node contains a pointer to the previous as well as the next node in the
sequence. Therefore, in a doubly-linked list, a node consists of three parts:
node data, pointer to the next node in sequence (next pointer), and pointer to
the previous node (previous pointer).
Circular singly linked list - In a circular singly linked list, the last node of the
list contains a pointer to the first node of the list. We can have circular singly
linked list as well as circular doubly linked list.
Circular doubly linked list - Circular doubly linked list is a more complex
type of data structure in which a node contains pointers to its previous node as
well as the next node. Circular doubly linked list doesn't contain NULL in any
of the nodes. The last node of the list contains the address of the first node of
the list. The first node of the list also contains the address of the last node in its
previous pointer.
Displaying the contents of a linked list is very simple. We keep moving the temp node
to the next one and display its contents.
When temp is NULL, we know that we have reached the end of the linked list so we get
out of the while loop.
Algorithm
Step 2 - If it is Empty then, display 'List is Empty!!!' and terminate the function.
Step 3 - If it is Not Empty then, define a Node pointer 'temp' and initialize with head.
Step 4 - Keep displaying temp → data with an arrow (--->) until temp reaches to the
last node
Step 5 - Finally display temp → data with arrow pointing to NULL (temp → data --->
NULL).
void display()
{
if(head == NULL)
{
printf("\nList is Empty\n");
}
else
{
struct Node *temp = head;
printf("\n\nList elements are - \n");
while(temp->next != NULL)
{
printf("%d --->",temp->data);
temp = temp->next;
}
printf("%d --->NULL",temp->data);
}
In the insertion operation to the empty linked list, we create a new node pointed
by the pointer temp and its data value is inserted to data part and link part set to
null.
Insertion to the non-empty linked list – initially the pointer temp points to the
first node in the list. The pointer temp is used to traverse along the list to reach the
end of the node.
You can add elements to either the beginning, middle or end of the linked list.
Store data
Algorithm
Step 4 - If it is Not Empty then, set newNode→next = head and head = newNode.
Store data
Algorithm
Step 1 - Create a newNode with given value and newNode → next as NULL.
Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.
Step 5 - Keep moving the temp to its next node until it reaches to the last node in the
list (until temp → next is equal to NULL).
Algorithm
Step 3 - If it is Empty then, set newNode → next = NULL and head = newNode.
Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.
Step 5 - Keep moving the temp to its next node until it reaches to the node after which
we want to insert the newNode (until temp1 → data is equal to location, here location
is the node value after which we want to insert the newNode).
Step 6 - Every time check whether temp is reached to last node or not. If it is reached
to last node then display 'Given node is not found in the list!!! Insertion not
possible!!!' and terminate the function. Otherwise move the temp to next node.
In a single linked list, the deletion operation can be performed in three ways. They are as
follows...
void insertAtBeginning(int);
void insertAtEnd(int);
void insertBetween(int,int,int);
void display();
void removeBeginning();
void removeEnd();
void removeSpecific(int);
struct Node
{
int data;
struct Node *next;
}*head = NULL;
void main()
{
int choice,value,choice1,loc1,loc2;
clrscr();
while(1){
mainMenu: printf("\n\n****** MENU ******\n1. Insert\n2. Display\n3. Delete\n
4. Exit\nEnter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter the value to be insert: ");
scanf("%d",&value);
while(1){
printf("Where you want to insert: \n1. At Beginning\n2. At End\n3. Betwee
n\nEnter your choice: ");
scanf("%d",&choice1);
switch(choice1)
{
case 1: insertAtBeginning(value);
break;
case 2: insertAtEnd(value);
break;
case 3: printf("Enter the value after which you want to insert: ");
scanf("%d%d",&item);
insertBetween(value,item);
break;
default: printf("\nWrong Input!! Try again!!!\n\n");
goto mainMenu;
}
goto subMenuEnd;
}
subMenuEnd:
break;
case 2: display();
break;
case 3: printf("How do you want to Delete: \n1. From Beginning\n2. From End\
n3. Spesific\nEnter your choice: ");
scanf("%d",&choice1);
switch(choice1)
{
case 1: removeBeginning();
break;
case 2: removeEnd();
break;
case 3: printf("Enter the value which you wanto delete: ");
scanf("%d",&loc2);
removeSpecific(loc2);
break;
default: printf("\nWrong Input!! Try again!!!\n\n");
goto mainMenu;
}
break;
case 4: exit(0);
default: printf("\nWrong input!!! Try again!!\n\n");
}
}
}
void insertAtBeginning(int value)
{
struct Node *newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
if(head == NULL)
{
newNode->next = NULL;
head = newNode;
}
else
{
newNode->next = head;
head = newNode;
}
printf("\nOne node inserted!!!\n");
}
void insertAtEnd(int value)
{
struct Node *newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
if(head == NULL)
head = newNode;
else
{
struct Node *temp = head;
while(temp->next != NULL)
temp = temp->next;
temp->next = newNode;
}
printf("\nOne node inserted!!!\n");
}
void insertBetween(int value, int loc1)
{
struct Node *newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
if(head == NULL)
{
newNode->next = NULL;
head = newNode;
}
else
{
struct Node *temp = head;
while(temp->data != item)
temp = temp->next;
newNode->next = temp->next;
temp->next = newNode;
}
printf("\nOne node inserted!!!\n");
}
void removeBeginning()
{
if(head == NULL)
printf("\n\nList is Empty!!!");
else
{
struct Node *temp = head;
if(head->next == NULL)
{
head = NULL;
free(temp);
}
else
{
head = temp->next;
free(temp);
printf("\nOne node deleted!!!\n\n");
}
}
}
void removeEnd()
{
if(head == NULL)
{
printf("\nList is Empty!!!\n");
}
else
{
struct Node *temp1 = head,*temp2;
if(head->next == NULL)
head = NULL;
else
{
while(temp1->next != NULL)
{
temp2 = temp1;
temp1 = temp1->next;
}
temp2->next = NULL;
}
free(temp1);
printf("\nOne node deleted!!!\n\n");
}
}
void removeSpecific(int delValue)
{
struct Node *temp1 = head, *temp2;
while(temp1->data != delValue)
{
if(temp1 -> next == NULL){
printf("\nGiven node not found in the list!!!");
goto functionEnd;
}
temp2 = temp1;
temp1 = temp1 -> next;
}
temp2 -> next = temp1 -> next;
free(temp1);
printf("\nOne node deleted!!!\n\n");
functionEnd:
}
void display()
{
if(head == NULL)
{
printf("\nList is Empty\n");
}
else
{
struct Node *temp = head;
printf("\n\nList elements are - \n");
while(temp->next != NULL)
{
printf("%d --->",temp->data);
temp = temp->next;
}
printf("%d --->NULL",temp->data);
}
}
Linked list insertion algorithms – complexity
1. Insertion at beginning - O(1)
2. Insertion at end- O(n)
3. Insertion at middle- O(n)
In general the complexity of algorithm to insert a node into the linked list-O(n)
Linked list deletion algorithms – complexity
1. Deletion at beginning -O(1)
2. Deletion at end-O(n)
3. Deletion at middle-O(n)
In general the complexity of algorithm to delete a node into the linked list-O(n)
Algorithm to insert one node at the end in the circular linked list
Step1: Start
Step 2: Let first points to the first node and last points to the last
node in the linked list.
Step 3: Read the data for new node into d
Step 4: If first=NULL then go to step 5 else go to step 7
Step 5: Create a new node pointed by temp.
Step 5.1: Set temp->data= d
Step 5.2: Set first=last = temp.
Step 6: Set temp->link=first
Step 7: If first ≠ NULL then go to step 8
Step 8: Create a new node pointed by temp
Step 8.1: Set temp->data=d
Step 8.2: Set last->link=temp
Step 8.2: Set temp->link= first
Step 9: Set last= temp
Step 10: Display the data in the nodes of the linked list
Step 11: Stop
PROGRAM:
struct node
{ int data;
struct node *link;
};
struct node *first=NULL;
struct node *last=NULL;
void insert(int item)
{
struct node *temp;
temp=(struct node *)malloc(sizeof(struct node));
temp->data=item;
if(first==NULL)
{
first=last=temp;
temp->link=first;
}
else
{
}
}
void main()
{
last->link=temp;
temp->link=first;
last=temp;
int item;
printf("enter the data item\n");
scanf("%d",&item);
insert(item);
}
Doubly linked list
Each node in the doubly linked list has three parts: previous, data, next. The data
part contains the data element while the next and previous parts contains the
addresses of the next and previous nodes respectively.
The main advantage of a doubly linked list is that it allows both forward and backward
traversal.
struct node
{
int data;
struct node *next;
struct node *previous;
};
Insert operation: Insert operation in the doubly linked list is the same manner as a
singly linked list. The only exception is that the additional node pointer previous is
also required to be updated for the new node at the time of insertion.
Algorithm for insert function in doubly linked list - insert at end (data)
Step1: Start
Step 2: Let first points to the first node and last points to the last node in the linked list.
Step 3: Read the data for new node into d
Step 4: If first=NULL then go to step 5 else go to step 6
Step 5: Create a new node pointed by temp.
Step 5.1: Set temp->data= d
Step 5.2: Set temp->next=NULL
Step 5.3:Set temp->previous=NULL
Step 5.4:Set first=last=temp
(Write program or algorithm for insertion-function into the doubly linked list)
PROGRAM:
struct node
{
int data;
struct node *next;
struct node *previous;
};
struct node *first=NULL;
struct node *last=NULL;
void insert( int num)
{
struct node *temp; // declare a pointer temp
temp=first; // the pointer temp points to the first node
if(temp==NULL) // if linked list is empty
{
temp=(struct node*)malloc(sizeof(struct node)); //
creates new node temp->data=num;
temp->next=NULL;
temp->previous=NULL;
first=last=temp; // inserts the new node to the list.
}
else{ // if linked list is non-empty
struct node *r;
temp=last;
r=(struct node*)malloc(sizeof(struct node));
r->data=num;
r->next=NULL;
r->previous=temp;
temp->next=r;
last=r; // inserts the new node at the last of the list.
}}
Header Linked list
A header linked list is a linked list which always contains a special node, called
header node, at the beginning of the list.
1. A grounded header list is a header list where the last node contains the null
pointer.
2. A circular header list is a header list where the last node points back to the header
node.
Grounded Header list
START
4000
Header node
5000 1 NULL
4000 5000
Circular Header list
START
4000
Header node
5000 1 4000
4000 5000
Binary Search Algorithm
Searching is the process of finding some particular element in the list. If the element is
present in the list, then the process is called successful, and the process returns the location
of that element. Otherwise, the search is called unsuccessful.
Linear Search and Binary Search are the two popular searching techniques. Here we will
discuss the Binary Search Algorithm.
Binary search is the search technique that works efficiently on sorted lists. Hence, to search
an element into some list using the binary search technique, we must ensure that the list is
sorted.
Binary search follows the divide and conquer approach in which the list is divided into two
halves, and the item is compared with the middle element of the list. If the match is found
then, the location of the middle element is returned. Otherwise, we search into either of the
halves depending upon the result produced through the match.
The recursive method of binary search follows the divide and conquer approach.
We have to use the below formula to calculate the mid of the array -
beg = 0
end = 8
1. Time Complexity
Case Time Complexity
o Best Case Complexity - In Binary search, best case occurs when the element to search is found in
first comparison, i.e., when the first middle element itself is the element to be searched. The best-
case time complexity of Binary search is O(1).
o Average Case Complexity - The average case time complexity of Binary search is O(logn).
o Worst Case Complexity - In Binary search, the worst case occurs, when we have to keep reducing
the search space till it has only one element. The worst-case time complexity of Binary search
is O(logn).
2. Space Complexity
Space Complexity O(1)
#include<stdio.h>
void main()
{
int arr[10],i,n,beg,end,num;
printf("enter the number of elements in the array in sorted order\n");
scanf("%d",&n);
printf("enter the elements\n");
for (i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
printf("The elements are : \n");
for (i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
beg=0;
end=n-1;
BinarySearch(arr,num,beg,end);
}
}
else
{
if(arr[mid]==num)
{
printf("Element Is At The Index: %d ",mid+1);
exit(0);
}
else if(arr[mid] > num)
{
BinarySearch(arr, num, first, mid-1);
}
else
{
BinarySearch(arr, num, mid+1, last);
}
}
}