Module-1 Linear Lists
Module-1 Linear Lists
A linked list is a linear data structure that includes a series of connected nodes
where each node contains data and address of the next node. A pointer called
head/first always points to the first node of the linked list and helps to traverse
and perform various operations.
There are many applications of linked lists and one of them is polynomial
representation and their operations.
Here each node contains the data of each term(coefficient and exponent). One
entire linked list is used to represent one polynomial.
A polynomial is summation of terms. Each term in a polynomial contains:
• Coefficient
• Exponent
When we represent a polynomial using a linked list, Each node contains a value
of exponent (int datatype), coefficient (int datatype) and the address of the
next node (pointer) and is implemented by defining a structure.
struct node
{
int coeff;
int expo;
struct Node *next;
}*head=NULL,*newnode,*p,*poly1,*poly2;
Apart from the main function, we write two other user-defined functions:
create_poly() and display() to store the given polynomial using linked list and
display it respectively.
Main function:
The main function is used to create 2 polynomials and display them by calling
the required functions.
void main()
{
printf("Enter the first polynomial\n");
poly1=create_poly();
printf("Enter the second polynomial\n");
poly2=create_poly();
printf("Polynomials:");
display(poly1);
display(poly2);
}
As the create_poly() function returns the head pointer of the polynomial
created, we declare two pointers- *poly1 and *poly2 to store the returned
values. So, *poly1 acts as the head pointer of the first polynomial and *poly2 to
the second one. These pointers are used in display function for traversal.
Create Function:
We declare the create function without parameter, with return value (it returns
a pointer of struct node datatype).
struct node* create_poly()
{
head=NULL; int n,i;
printf("Enter the no. of terms in polynomial\n");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
newnode=(struct node*)malloc(sizeof(struct node));
printf("Enter the coefficient and exponent\n”);
scanf("%d%d",&newnode->coeff,&newnode->expo);
newnode->next=NULL;
if(head==NULL) //when the first node is created
head=p=newnode;
else//for all other nodes
p->next=newnode;
p=newnode;
}
return head;
}
• The pointer head must be initialized to NULL at the beginning because
we are creating multiple linked lists using the function and *head still
points to the previous linked list if it’s not initialized.
• After allocating memory and entering the data into the newnode, It’s
address is stored in p->next (it is connected to the last node). As the
newnode become the last node now, *p moves to the newnode.
After iteration 1:
After iteration 2:
Display Function:
Display function is declared without return value, with one parameter. The
head pointer of the polynomial to be displayed is sent to the function. We use
*p as a formal parameter and traverse through the linked list using it.
void display(struct node *p)
{
if(p==NULL) // When the linked list is empty
printf("There is no polynomial\n");
else
{
while(p->next!=NULL)
{
printf("%dx^%d + ",p->coeff,p->expo);
p=p->next;
}
printf("%dx^%d\n",p->coeff,p->expo);
}
}
• By using a while loop, all the terms except the last term are printed
• The last term is printed after the loop by replacing “+” with “\n” at the
end of the text.
The output format of the polynomial is:
4x^3 + 3x^2 + 6x^1 + 7x^0
to the p2=p2->next;
result }
else if (p1->expo==p2->expo)
{
If the exponent of a term in p2 and p1 are equal, the
temp->co=p1->co+p2->co; sum of the co-efficients of both the terms becomes the
temp->expo=p1->expo; coefficient in the result and both p1 and p2 are moved
to the next node.
p1=p1->next;
p2=p2->next;
}
} //end of the while loop
while(p1!=NULL)
{ After the end of while loop,
one of the polynomials might
temp->next=(struct node*)malloc(sizeof(struct node));
still have terms left. If
temp=temp->next; (p1!=NULL), its remaining
temp->co=p1->co; terms are transferred into the
result.
To copy temp->expo=p1->expo;
the data p1=p1->next;
from }
rest of while(p2!=NULL)
the {
nodes temp->next=(struct node*)malloc(sizeof(struct node));
If (p2!=NULL), its remaining
temp=temp->next;
terms are transferred into the
temp->co=p2->co; result.
temp->expo=p2->expo;
p2=p2->next;
}
temp->next=NULL;
return res;
}
Polymul() function:
To multiply two polynomials, we multiply the 2nd polynomial with each term of
1st polynomial. Then, we add the coefficients of terms having the same power
in resultant polynomial.
Example:
Poly1: 3x^2 + 5x^1 + 6
Poly2: 6x^1 + 8
On multiplying each element of 1st polynomial with elements of 2nd
polynomial, we get 18x^3 + 24x^2 + 30x^2 + 40x^1 + 36x^1 + 48
On adding values with same power of x, we get:
18x^3 + 54x^2 + 76x^1 + 48
{
if(res==NULL) //to create the first node
{
res=(struct node*) malloc(sizeof(struct node));
temp=t=res;
}
else//for all other nodes
{
while(t) //to add terms with same exponents
{
if(t->expo==p1->expo+p2->expo)
*t is traversed throughout the result
{
linked list to check if any exponent is
t->co+=p1->co*p2->co; equal to the exponent of the current
flag=1;break; product term. If it is, the product of
coefficients is added to the existing
} coefficient in the result and comes
else out of the loop.
t=t->next;
}
if(flag==1)
flag==1 when the product exponent already exists
{ in the result and as we have already entered the
p2=p2->next; coefficient in the above loop, we move the p2 to
the next node, reset *t to head and use the
t=res; continue statement to ignore the rest of the
flag=0;continue; statements in this iteration
}
temp->next = (struct node *) malloc(sizeof(struct node));
temp=temp->next; Otherwise, a new
node is created. The
} product of
temp->co=p1->co*p2->co; coefficients becomes
the result’s
temp->expo=p1->expo+p2->expo; coefficient. The sum
temp->next=NULL; of exponents is the
exponent in result.
p2=p2->next; t=res;
}
p2=pt; //reset p2 to make it point to first node
p1=p1->next;
}
return res;
}
CIRCULAR LINKED LIST:
The circular linked list is a linked list where all nodes are connected to form a
circle. In a circular linked list, the first node and the last node are connected to
each other which forms a circle. There is no NULL at the end.
Head
The structure definition for circular queue is similar to that of singly linked list
struct node
{
int data;
struct node *next;
}*head=NULL,*last,*newnode,*p;
Create() function:
void create()
{
int i,n;
printf(“Enter the no of nodes\n”);
scanf(“%d”,&n);
for(i=1;i<=n;i++)
{
newnode=(struct node*)malloc(sizeof(struct node));
printf(“Enter the data\n”);
scanf(“%d”,&newnode->data);
if(head==NULL)
head=last=newnode;
else
last->next=newnode;
last=newnode;
}
last->next=head;
}
The create function is similar to the one in singly linked list but the last node
stores the address of the first node instead of NULL.
Display() function:
void display()
{
if(head==NULL)
printf(“Circular linked list is empty\n”);
else
{
p=head;
printf(“The elements are”);
do
{
printf(“%3d”,p->data);
p=p->next;
} while(p!=head);
printf(“\n”);
}
}
We use the pointer *p to traverse through the circular linked list. The traversal
terminates when the pointer returns to the first node.
Insertion at beginning:
void insbeg()
{
newnode=(struct node*)malloc(sizeof(struct node));
printf(“Enter the data to insert”);
scanf(“%d”,&newnode->data);
newnode->next=head;
last->next=newnode;
head=newnode;
}
• store the address of the current first node in the newNode (i.e. pointing
the newNode to the current first node.
• point the last node to newNode (i.e making newNode as first node)
• update head to make it point to first node
Insertion at ending:
void insend()
{
newnode=(struct node*)malloc(sizeof(struct node));
printf(“Enter the data to insert”);
scanf(“%d”,&newnode->data);
newnode->next=head;
last->next=newnode;
last=newnode;
}
void insmid()
int pos,i;
scanf(“%d”,&pos);
newnode=(struct node*)malloc(sizeof(struct node));
scanf(“%d”,&newnode->data);
newnode->next=newnode;
head=last=newnode;
else
p=head;
for(i=2;i<pos;i++)
p=p->next;
newnode->next=p->next;
p->next=newnode;
Explanation:
• As the insertion in the queue is from the rear end and in the case of
Linear Queue of fixed size insertion is not possible when rear reaches
the end of the queue.
• But in the case of Circular Queue, the rear end moves from the last
position to the front position circularly
The structure definition for circular queue is similar to that of singly linked list
struct node
{
int data;
struct node *next;
}*front=NULL,*rear=NULL,*newnode,*temp;
Enqueue() Function:
Enqueue function is used to insert data into the queue which is generally done
at the rear end.
void enqueue(int x)
{
newnode=(struct node*)malloc(sizeof(struct node));
newnode->data=x;
if(rear==NULL) //creating the first node
{
rear=front=newnode;
rear->next=front;
}
else
{
rear->next=newnode;
rear=newnode;
rear->next=front;
}
}
Example: insert 10,20,30,40
Dequeue() function:
Dequeue function is used to delete data from the queue which is generally
done from the front end.
void dequeue()
{
temp=front;
if((rear==NULL)&&(front==NULL)) //when Queue is empty
printf("Queue is empty\n");
else if(front==rear) //When there is only one node
{
front=rear=NULL;
printf("The deleted element is %d\n",temp->data);
free(temp);
}
else
{
front=front->next;
rear->next=front;
printf("The deleted element is %d\n",temp->data);
free(temp);
}
}
Example: delete; delete;
Front() function:
Front function is used to display the front element in the queue. As we already
use “front” as the name of the pointer, we declare the function as first().
void first()
{
if((rear==NULL)&&(front==NULL))
printf("Queue is empty\n");
else
printf("The front element is %d\n",front->data);
}
Rear() function:
Front function is used to display the last element in the queue. As we already
use “rear” as the name of the pointer, we declare the function as last().
void last()
{
if((rear==NULL)&&(front==NULL))
printf("Queue is empty\n");
else
printf("The last element is %d\n",rear->data);
}
Display() function:
This function is used to display all the elements in the queue from front to rear.
void display()
{
temp=front;
if((rear==NULL)&&(front==NULL))
printf("Queue is empty\n");
else
{
printf("The elements are ");
do
{
printf("%3d",temp->data);
temp=temp->next;
}while(temp!=front);
printf("\n");
}
}
• We use a pointer called temp to traverse and display all the elements.
struct node
{
int data;
struct node *prev,*next;
}*front=NULL,*rear=NULL,*newnode,*p,*q;
Create() function:
We create a doubly linked list to implement the deque.
void create()
{
int n,i;
printf("Enter the no of nodes\n");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
newnode=(struct node *) malloc(sizeof(struct node));
printf("Enter the data\n");
scanf("%d",&newnode->data);
newnode->next=NULL;
newnode->prev=NULL;
if(front==NULL)// to create the first node
front=rear=newnode;
else
{
rear->next=newnode;
newnode->prev=rear;
rear=newnode;
}
size++; //to count the no of nodes
}
}
Display() function:
We traverse the deque using two pointers *p and *q. As it is the doubly linked
list, traversal can be done in both directions.
void display()
{
q=front; p=rear;
printf("The elements are ");
while(q) //traversal from front to rear
{
printf("%3d",q->data);
q=q->next;
}
printf("\nThe elements in reverse order are ");
while(p) //traversal from rear to front
{
printf("%3d",p->data);
p=p->prev;
}
printf("\n");
}
InsertFront() function:
We declare this function without return value, with one parameter. A newnode
with data is inserted at the beginning of the deque which becomes the new
front.
void InsertFront(int x)
{
newnode=(struct node *)malloc(sizeof(struct node));
newnode->data=x;
newnode->next=NULL; newnode->prev=NULL;
if (front == NULL) //when deque is empty
rear = front = newnode;
else
{
newnode->next = front;
front->prev = newnode;
front = newnode;
}
size++;
}
InsertRear() function:
We declare this function without return value, with one parameter. A newnode
with data is inserted at the end of the deque which becomes the new rear.
Void InsertRear(int x)
{
newnode=(struct node *)malloc(sizeof(struct node));
newnode->data=x;
newnode->next=NULL; newnode->prev=NULL;
if (front == NULL) //when deque is empty
rear = front = newnode;
else
{
newnode->prev = rear;
rear->next = newnode;
rear = newnode;
}
size++;
}
DeleteFront() function:
The first node of the deque is deleted after passing the front pointer to the
next node.
void DeleteFront()
{
if(front==NULL) //When Deque is empty
printf("Deque is empty\n");
else
{
p=front;
front=front->next;
if(front==NULL) //When there is only one node
rear=NULL;
else
front->prev=NULL;
free(p);
size--;
}
}
DeleteRear() function:
The last node of the deque is deleted after passing the rear pointer to the
previous node.
void DeleteRear()
{
if(front==NULL) //When Deque is empty
printf("Deque is empty\n");
else
{
p=rear;
rear=rear->prev;
if(rear==NULL) //When there is only one node
front=NULL;
else
rear->next=NULL;
free(p);
size--;
}
}
getFront() function:
This function displays the first element of the deque.
void getFront()
{
if (front==NULL)
printf("Queue is empty\n");
else
printf("The front element is %d \n", front->data);
}
getRear function:
This function displays the last element of the deque.
void getRear()
{
if (front==NULL)
printf("Queue is empty\n");
else
printf("The last element is %d\n ", rear->data);
}
qsize() function:
void qsize()
{
printf ("The no of nodes in queue are %d\n",size);
}
PRIORITY QUEUE
A priority queue is a type of queue that arranges elements based on their
priority values. When you add an element to the queue, it is inserted in a
position based on its priority value.
• In a priority queue, An element with high priority is dequeued before an
element with low priority.
• If two elements have the same priority, they are served according to
their order in the queue.
Example: The following example shows a priority queue with elements of
priority 10 (highest priority), 20, etc., to 80 (lowest priority). Another element
with priority 45 is inserted into the queue. The queue then automatically
ensures that this element is inserted after the element with priority 40 and
before the element with priority 50. When dequeue is performed element is
deleted from front i.e., an element with high priority.
In a priority queue, Each element has a priority. So, each node needs to store
the priority value along with data and pointer.
struct node
{
int priority;
int data;
struct node *next;
}*front=NULL,*rear=NULL,*newnode,*p;
Insert() function:
For this function, The data and priority of the element to be inserted are given
as the parameters. While inserting an element into the priority list, the priority
of the element is compared and inserted accordingly at accurate position.
void insert(int data,int priority)
{
newnode=(struct node*)malloc(sizeof(struct node));
newnode->data=data; Creating a node
newnode->priority=priority;
if(front==NULL || priority<front->priority)
{
When the new node must be
newnode->next=front;
the first node
front=newnode;
}
else
{
p=front;
while((p->next!=NULL) && (p->next->priority<=priority)) Traversing to go the
p=p->next; required position
newnode->next=p->next;
p->next=newnode;
}
}
• p will traverse till the node after which priority value is greater than
newnode’s priority value. Newnode is inserted right after p.
Delete() function:
In the priority queue, the element with the highest priority (lowest numerical
value of priority) is placed at the front end. We simply dequeue/delete the first
element after moving the front pointer to the next node.
void del()
{
if(front==NULL) //when the queue is empty
printf("Queue Underflow\n");
else
{
p=front;
front=front->next;
free(p);
}
Peek() function:
This function is used to display the front element in the queue.
void peek()
{
if((front==NULL)&&(rear==NULL)) //when the queue is empty
printf("Queue is empty\n");
else
printf("The front element is %d \n",front->data);
}
Display() function:
This function is used to display all the elements in the queue along with their
priorities.
void display()
{
if((front==NULL)&&(rear==NULL)) //when the queue is empty
printf("Queue is empty\n");
else
{
p=front;
printf("The elements in a queue are\n ");
while(p)
{
printf("%3d %3d\n",p->data,p->priority);
p=p->next;
}
}
}
• *p is used to traverse and display the elements.
Note: In all the programs, linked list pointers are not declared in the user-
defined functions because all the pointers are assumed to be declared globally
when the struct node is defined.