0% found this document useful (0 votes)
42 views

DS Unit 2-Notes

Queue is a linear data structure where elements are inserted at the rear end and deleted at the front end, following FIFO (First In First Out) principle. There are different types of queues - linear, circular, and priority. Circular queues improve on linear queues by allowing insertion when the queue is full via a circular buffer that connects the rear to the front. Common applications of queues include operating systems, simulation, buffering, and media playback.

Uploaded by

Amisha Shetty
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)
42 views

DS Unit 2-Notes

Queue is a linear data structure where elements are inserted at the rear end and deleted at the front end, following FIFO (First In First Out) principle. There are different types of queues - linear, circular, and priority. Circular queues improve on linear queues by allowing insertion when the queue is full via a circular buffer that connects the rear to the front. Common applications of queues include operating systems, simulation, buffering, and media playback.

Uploaded by

Amisha Shetty
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/ 68

UNIT 2

Linear Data structures- Queue


Queue

It is a linear structure where elements are inserted from one end and elements are
deleted from other end. The end at which new elements are added is called rear and
the end from which elements are deleted is called front. Using the approach, first
element inserted is the first element to be deleted out, hence queue can be called First
in First out (FIFO) data structure. A good example of queue is any queue of consumers
for a resource where the consumer that came first is served first.

The difference between stacks and queues is in removing. In a stack we remove the
item the most recently added; in a queue, we remove the item the least recently
added.

Different types of queue:


a) Linear queue (Ordinary queue)

b) Circular queue

c) Priority queue

a) Linear queue:

Here elements will be inserted from one end and elements are deleted from other end.
The end at which new elements are added is called rear and the end from which
elements are deleted is called front.

Eg: Consider the queue having the elements 10, 50 and 20.

10 50 20

0 1 2 3 4

front rear

Here the items are inserted into queue in the order 10, 50 and 20. The variable q is
used as an array to hold these elements. Item 10 is the first element inserted. So, the
variable first is used as index to the first element. Item 20 is the last element
inserted. So, the variable rear is used as index to the last element.

Operations on Queue:

Insertion:
Step 1:

QUEUE_SIZE = 5

10 20 30 40 50

0 1 2 3 4

front rear

We can observe that whenever rear value is equal to “QUEUE_SIZE -1” insertion is not
possible. The code for this can be written as:

if (rear==QUEUE_SIZE -1)

{ printf(“Queue is

full\n”); return;

Step 2: If the condition QUEUE_SIZE – 1 is not satisfied, it means the queue is not full
and an element can be inserted at the rear end. Observe that item has to be after 30
at position 3. That is, before inserting an item, we have to increment rear by one. This
can be achieved by rear = rear +1; Item = 40

10 20 30

0 1 2 3 4

front rear

Step 3: Now the item can be inserted at rear position. This can be achieved by copying
item into q[rear] as: q[rear] = item; Item = 40

10 20 30 40

0 1 2 3 4

front rear
C Function to insert an item at the rear end of queue:

void Insert_Rear()

if(rear==QUEUE_SIZE – 1) //check for overflow of queue

printf(“Queue overflow\n”); return;

rear = rear +1;


q[rear] = item; //insert the item

Deletion:

In queue, an item is always removed from the front end of queue.

Step 1: To check whether queue is empty or not?

10 20 30

0 1 2 3 4

front rear

3 items are present in queue

front < rear

10 20 30

0 1 2 3 4

front

rear

front == rear
So we can see the above 2 figures that if front is less than or equal to rear some
elements are present. Otherwise, it that is front is greater than rear then queue is
empty. We can check for empty queue using the following statement:

if (front > rear) return -1 //Queue is empty

Step 2: When the above condition fails, we can delete an item from a front end of
queue. So for this, we have to access and return the first element and increment
value of front by 1 as:

return q[front++];

C function to delete an element from the front end of queue:

int delete_Front()
{

if(front> rear) return -1; return

q[front++];

Display:

Step 1: Check for empty queue:

if(front>rear)

printf(“Queue is empty”); return;

Step 2: If elements are present in queue control comes out of the above if statements.
Assume that queue contains 3 elements:

20 25 10

-1 0 1 2 3 4

front rear

The contents of queue can be displayed as:


printf(“%d\n”,s[0]); Output: 20 printf(“%d\n”,s[1]);

25 printf(“%d\n”,s[2]); 10

In general we use printf(“%d\n”,s[i]); Now

the code takes the following form:

for(i=front;i<=rear;i++)

{ printf(“%d\n”,s[i]);

C function to display:
void display()

if(front>rear) //if queue is empty

printf(“queue is empty\n”); return;

printf("\ncontents of queues are: "); //display contents of queue for(i=front;i<=rear;i++)

printf("%d",q[i]);

}}

Real world examples of Queue:

1. Simulation and operating system

2. Operating system maintains a queue of processes that are ready to execute or


that are ready to execute.

3. The holding area in computer system for communicating messages between 2


processes is usually called buffer which is implemented as a queue.

Drawback of ordinary Queue:

Consider the queue shown below:


The above situation arises when 5 elements say 10, 20,30,40,50 are inserted and then
deleting first 2 items 10 and 20. It is not possible to insert an item. Even if there is
space available insertion cannot be made. Because we have Queue Overflow
condition as QSIZE-1. This is the drawback of an ordinary queue.

Applications of Queue
1. Queues are widely used as waiting lists for a single shared resource like printer,
disk, CPU.
2. Queues are used in asynchronous transfer of data (where data is not being
transferred at the same rate between two processes) for eg. pipes, file IO,
sockets.
3. Queues are used as buffers in most of the applications like MP3 media player,
CD player, etc.
4. Queue are used to maintain the play list in media players in order to add and
remove the songs from the play-list.
5. Queues are used in operating systems for handling interrupts.

C Program to implement ordinary queue using global variables:

#include <stdio.h>
#include <stdlib.h>
#define que_size 5 int
rear,front,item,q[10];
void insertq()

{
if (rear==que_size-1) //check for overflow of queue
printf("QUEUE OVERFLOW \n");

else
{
rear=rear+1; //increment rear and insert item
q[rear]=item;

}
}
int deleteq()
{
if(front>rear) //Queue is empty
return-1; else
return(q[front++]);
}
void display()
{
int i;

if(front>rear) //check for empty queue


printf("QUEUE UNDERFLOW \n");

else
{
for(i=front;i<=rear;i++)
{
printf("%d\t",q[i]); //here contents of queue is displayed
}
printf("\n");

}
}
int main()
{
int ch, delitem;
front=0; rear=-1;
while(1)

{
printf("1.INSERT 2.DELETE 3.DISPLAY 4.EXIT \n");
printf("ENTER YOUR CHOICE \n");
scanf("%d",&ch); switch(ch)

{
case 1:printf("ENTER THE ITEM \n");
scanf("%d",&item); insertq();
break; case 2: delitem=deleteq();
if(delitem==-1)
printf("QUEUE UNDERFLOW \n");
else
printf("DELETED ITEM = %d\n",delitem);
break;
case 3: display();
break; case
4:exit(0);

default :printf("INVALID CHOICE !!! TRY AGAIN\n");


break;

}}

return 0;
}
Output:
Representation of queue using structure struct

queue

{ int

item[size]; int

rear, front;
}q;

The initial value of rear and front when queue is empty is as follows.

Rear=-1 and front=0;

Size is the maximum size of the array used.

b) Circular Queue:

Circular Queue is a linear data structure in which the operations are performed based
on FIFO (First in First Out) principle and the last position is connected back to the
first position to make a circle. It is also called ‘Ring Buffer’.

Queue operations work as follows:

• Two pointers called FRONT and REAR are used to keep track of the first and last
elements in the queue.

• When initializing the queue, we set the value of FRONT and REAR to -1.
• On enqueing an element, we circularly increase the value of REAR index and
place the new element in the position pointed to by REAR.

• On dequeing an element, we return the value pointed to by FRONT and circularly


increase the FRONT index.

• Before enqueing, we check if queue is already full.


• Before dequeing, we check if queue is already empty.
• When enqueing the first element, we set the value of FRONT to 0.
• When dequeing the last element, we reset the values of FRONT and REAR to
-1.

Example:
In a normal Queue, we can insert elements until queue becomes full. But once queue
becomes full, we cannot insert the next element even if there is a space in front of
queue. Whenever front is 0 and rear either -1 or Queue_Size – 1, queue is empty.
Whenever item is inserted, rear is incremented by 1. Whenever we have to delete the
elements, then we have to delete at front end.

• Front: Get the front item from queue.


• Rear: Get the last item from queue.
• enQueue(value) This function is used to insert an element into the circular
queue. In a circular queue, the new element is always inserted at Rear position.

Steps:
1. Check whether queue is Full – Check ((rear == SIZE-1 && front == 0) || (rear
== front-1)).

2. If it is full then display Queue is full. If queue is not full then, check if (rear ==
SIZE – 1 && front != 0) if it is true then set rear=0 and insert element.

deQueue() This function is used to delete an element from the circular queue.
In a circular queue, the element is always deleted from front position.

Steps:
1. Check whether queue is Empty means check (front==-1).
2. If it is empty then display Queue is empty. If queue is not empty then step 3
3. Check if (front==rear) if it is true then set front=rear= -1 else check if
(front==size-1), if it is true then set front=0 and return the element.
Pictorial representation of circular queue:

When queue is empty, front =0 and rear =-1. But in circular queue just before index 0,
we have index 4. So instead of rear=-1 we can write rear=4 also. So empty queue is
represented by following initialization statements:

front=0; rear=-1;

The above statements indicate empty queue can also be represented as:

front=0; rear=4; //rear=4. In general

rear=Que_Size-1

Eg: The contents of circular queue after performing each of the following operations: a)

Empty queue

b) Insert 10

c) Insert 20 and 30

d) Insert 40 and 50

e) Insert 60

f) Delete 2 items

g) Insert 60
h) Insert 80
Step 1: Empty queue: Whenever front is 0 and rear is either -1 or QUE_SIZE -1, queue
is empty. An empty queue can be represented as:

Step 2: Insert 10: After incrementing rear by 1, 10 is inserted as:

Step 3: Insert 20 and 30: Here we have to increment rear by 1 and insert 20. Again
increment rear by 1 and insert 30 as:

Step 4: Insert 40 and 50: Increment rear by 1 and insert 40. Again increment rear by 1
and insert 50 as:

Step 5: Insert 60: Queue is full. It is not possible to insert any element into queue. So,
contents of queue have not been changed here.
Step 6: Delete: An item has to be deleted always from the front end. So, 10 is deleted
and contents of queue after deleting 10 is:

Step 7: Delete: An item has to be deleted always from the front end. So 20 is deleted
and contents of queue after deleting 20 is:

Step 8: Inserting 60: Increment rear by 1, its value is 0 and insert 60 at 0th location as:

Step 9: Inserting 70: Increment rear by 1 and insert 70 as:


Step 10: Insert 80: Queue is full. It is not possible to insert any element into queue.
So, contents of queue have not been changed.

InsertQ()

Step 1: Check for overflow: Before inserting an item, we check whether sufficient
space is available in the queue.

if(count==Queue_Size)

printf(“ Queue is full\n”); return;

Step 2: Insert item: Increment rear by 1 and then take the mod operation and then

insert the item as shown below: rear = (rear+1)%Queue_Size; q[rear]=item;

Step 3: Update count:

As we insert an element an item, the count is incremented by 1. This indicates at any


point of time; the variable count contains the total number of items present in the queue.

void InsertQ()
{

if(count==Que_Size)

printf(“Queue overflow”); return;

rear=(rear+1)%Que_Size;

q[rear]=item; count++;

DeleteQ():

Step 1: Check for underflow: Before deleting an element from queue, we check

whether sufficient queue is empty or not. This can be achieved using the statement:

if(count==0) return -1;

When the above condition fails, it means queue is not empty and return the element
present at the front end of queue.

Step 2: Access the first item: This is achieved by accessing the element using index
front and then updating front by adding 1 to it and then take mod value. The equivalent
statements can be written as:

item=q[front]; //access the item


front=(front+1)%Que_Size; //update front so that it contains index of next element

Step 3: Update count: As we delete an element from queue, decrement count by 1.


This is achieved using the following statement:

count--;

Step 4: Return the element which was at the front end using the statement:
return item;

C function to delete an item from the front end of circular queue:

int DeleteQ()

if(count==0) return -1; item =

q[front]; front =

(front+1)%Que_Size; count - =1;

//decrement the count return item;

DisplayQ():

Step 1: Check for underflow: This is achieved using the following statement:

if(count==0)

printf(“Queue is empty\n”); return;

Step 2: Display: Display starts from the front index. After displaying q[front] we have to
update front by 1. (That is by incrementing front by 1 and then taking the modulus).
The procedure is repeated for count number of times. This is because, count contains
the number of items in queue. The code can be written as:

for (i=1,f=front;i<=count;i++)

printf(“%d\n”,q[f]);

f=(f+1)%Que_Size;

}
C function to display the contents of circular queue:

void display()

{ int

i,f;

if(count==0)

printf(“Q is empty\n”); return;

printf(“Contents of queue is\n”); for(i=1,f=front;i<=count;i++)

printf(“%d\n”,q[f]);

f=(f+1)%Que_Size;

}
c) Priority Queue: A queue in which we are able to insert items or remove items from
any position based on some priority is often referred as Priority queue. Always an
element with highest priority is processed before processing any of the lower priority
elements. If the elements in the queue are of same priority, then the element which is
inserted first into the queue is processed.

The priority queue is classified into 2 groups:

Ascending priority queue:

In an ascending priority queue elements can be inserted in any order. But, while deleting
an element from the queue, only the smallest element is removed first.
Descending priority queue:

In descending priority queue also elements can be inserted in any order. But, while
deleting an element from the queue, only the largest element is deleted first.

How to implement priority queues?

There are various methods of implementing priority queue using arrays.

1) One method to implement an ascending priority queue where elements can be


inserted in any fashion and only the smallest element is removed. Here, an element
is inserted from rear end of the queue but an element with least value should be
deleted. After deleting the smallest number, store a very large value in that location,
indicating the absence of an item. The variable count can be used to keep track of
number of elements in the array.

The 3 functions useful for this purpose are:

insert_rear() – which inserts the item at the end of the queue.

remove_small() – which inserts the smallest item from the queue and at the same time

store maximum number in that location indicating an item has been deleted. display()

– which displays the content of the queue.

2) The second technique is to insert the item based on the priority. In this
technique, we assume the item to be inserted itself denotes the priority. So, the items
with least value can be considered as the items with highest priority and items with
highest value can be considered as the items with least priority. So, to implement
priority queue we insert the elements in queue in such a way that they are always
ordered in ascending order. With this technique the highest priority elements are at
front end of the queue and lowest priority elements are at rear end of the queue. So
while we are deleting an item, always delete from the front end so that highest priority
element is deleted first.

C code for the function to insert an item at the correct place in priority queue:

void insert_item(int item, int q[], int *r)


{ int

j;

if(*r==Queue_Size – 1) //Check for overflow

{ printf(“Q is

full\n”); return;

} j=*r; // compare from this initial rear

pointer

while(j>=0 && item <q[j]) //find appropriate position to allocate space for inserting an
item based on the priority

q[j+1]=q[j]; //Move the item at q[j] to its next position

j--;

q[j+1]=item; //insert an item at the appropriate position

*r=*r+1 //Update the rear pointer

}
Linear Data Structures- Singly Linked List

Dynamic Memory Allocation

C is a structured language, it has some fixed rules for programming. One of it includes
changing the size of an array. An array is collection of items stored at continuous
memory locations.
As it can be seen that the length (size) of the array above made is 9. But what if there
is a requirement to change this length (size). For Example,

• If there is a situation where only 5 elements are needed to be entered in this


array. In this case, the remaining 4 indices are just wasting memory in this
array. So there is a requirement to lessen the length (size) of the array from 9 to

5.
• Take another situation. In this, there is an array of 9 elements with all 9 indices
filled. But there is a need to enter 3 more elements in this array. In this case 3
indices more are required. So the length (size) of the array needs to be
changed from 9 to 12.

This procedure is referred to as Dynamic Memory Allocation in C.


Therefore, C Dynamic Memory Allocation can be defined as a procedure in which the size of
a data structure (like Array) is changed during the runtime.

The process of allocating memory at runtime is known as dynamic memory allocation.


Library routines is known as "memory management functions" which are used for
allocating and freeing memory during execution of a program.

Now let us see the difference between static memory allocation and dynamic memory
allocation:

static memory allocation dynamic memory allocation

memory is allocated at compile time. memory is allocated at run time.


memory can't be increased while memory can be increased while
executing program. executing program.

used in array. used in linked list.

C provides some functions to achieve these tasks. There are 4 library functions
provided by C defined under <stdlib.h> header file to assist dynamic memory allocation
in C programming. They are:

1. malloc()
2. calloc()
3. free()
4. realloc()
Function Description

malloc() allocates requested size of bytes and returns a void pointer pointing to
the first byte of the allocated space

calloc() allocates space for an array of elements, initialize them to zero and then
returns a void pointer to the memory

free releases previously allocated memory

realloc modify the size of previously allocated space

Malloc ()

malloc () function is used for allocating block of memory at runtime. This function reserves
a block of memory of given size and returns a pointer of type void. This means that we
can assign it to any type of pointer using typecasting. If it fails to allocate enough space
as specified, it returns a NULL pointer.

Syntax:
void* malloc(byte-size) Example

using malloc() :

int *x;

x = (int *)malloc(100*sizeof(int)); //Since the size of int is 4 bytes, this statement will allocate
400 bytes of memory. And, the pointer ptr holds the address of the first byte in the allocated
memory.

free(x);

calloc()

Calloc is also called “contiguous allocation”. calloc() is another memory allocation


function that is used for allocating memory at runtime. calloc function is normally used
for allocating memory to derived data types such as arrays and structures. If it fails to
allocate enough space as specified, it returns a NULL pointer.

Syntax:

void *calloc(number of items, element-size)

Example using calloc ():

ptr = (float*) calloc(25, sizeof(float)); //This statement allocates contiguous space in


memory for 25 elements each with the size of the float.
realloc()

realloc () changes memory size that is already allocated dynamically to a variable.


realloc in C is used to dynamically change the memory allocation of a previously allocated
memory. In other words, if the memory previously allocated with the help of malloc or calloc is
insufficient, realloc can be used to dynamically re-allocate memory. re-allocation of memory
maintains the already present value and new blocks will be initialized with default garbage
value. Syntax:

ptr = realloc(ptr, newSize); where ptr is

reallocated with new size 'newSize'.

Example using realloc() :

int *x; x=(int*)malloc(50 * sizeof(int)); x=(int*)realloc(x,100);

//allocated a new memory to variable x

If space is insufficient, allocation fails and returns a NULL pointer.


free():
“free” method in C is used to dynamically de-allocate the memory. The memory allocated
using functions malloc() and calloc() is not de-allocated on their own. Hence the free() method
is used, whenever the dynamic memory allocation takes place. It helps to reduce wastage of
memory by freeing it.

Syntax: free(ptr);

Difference between malloc() and calloc()

calloc() malloc()

calloc() initializes the allocated memory malloc() initializes the allocated memory
with 0 value. with garbage values.

Number of arguments is 2 Number of argument is 1

Syntax: Syntax:

(cast_type *)calloc(blocks , (cast_type *)malloc(Size_in_bytes);


size_of_block);

Program to represent Dynamic Memory Allocation(using calloc())

#include <stdio.h>
#include <stdlib.h> int

main()

{ int i,

n;

int *element; printf("Enter total number of

elements: "); scanf("%d", &n);

element = (int*) calloc(n,sizeof(int)); //returns a void pointer(which is type-casted to int*)


pointing to the first block of the allocated space

if(element == NULL) //If it fails to allocate enough space as specified, it returns a NULL
pointer.

printf("Error.Not enough space available");

exit(0);

for(i=0;i<n;i++) //storing elements from the user in the allocated space

scanf("%d",element+i); //storing elements from the user in the allocated space

for(i=1;i<n;i++)

if(*element > *(element+i))

*element = *(element+i);

}
printf("Smallest element is %d",*element);
return 0;

Output:

Enter total number of elements: 5

42153

Smallest element is 1

Linked list:

Definition: A linked list is a sequence of data structures which are connected together
via links. Linked List is a sequence of links which contains items. Each link contains a
connection to another link. A linked list is a non-primitive type of data structure in which
each element is dynamically allocated and in which elements point to each other to
define a linear relationship. If each node in the list has only one link, it is called singly
linked list. If it has two links one containing the address of the next node and other link
containing the address of the previous node it is called doubly linked list. Linked list
require more memory compared to array because along with value it stores pointer to
next node.

Elements of linked list are called nodes where each node in the singly list has 2 fields
namely:

• info – This field is used to store the data or information to be manipulated.


• link – This field contains address of the next node.
Linked list contains the connection link to the first Link called First. Each Link carries a
data field(s) and a Link Field called next. Last Link carries a Link as null to mark the
end of the list.

Advantages of Linked Lists over Arrays

1. A linked list is a dynamic data structure therefore, the primary advantage of


linked lists over arrays is that linked lists can grow or shrink in size during the execution
of a program i.e. runtime but arrays is a static data structure therefore, the size remain
fixed. In arrays we would need to allocate all the storage in starting.

2. There is no need to specify how many number of nodes required so linked list
does not waste memory space. We can allocate and de-allocate memory space at
runtime.

3. The most important advantage is that the linked lists provide flexibility is allowing
the items to be rearranged efficiently. In linked list it is easier to insert or delete items
by rearranging the pointers but in arrays insertion and deletion requires large
movement of data.

Disadvantages of Linked Lists over Arrays

1. A linked list will use more memory storage than arrays with the same number of
elements is used because each time linked list has more memory for an additional
linked field or next pointer field.

2. Arrays elements can be randomly accessed by giving the appropriate index, while
linked list elements cannot randomly accessed.

3. Binary search cannot be applied in a linked list.

4. A linked list takes more time in traversing of elements.


Operations on singly linked list:

The following operations are performed on a Single Linked List:

• Insertion
• Deletion
• Display

Insertion: In a single linked list, the insertion operation can be performed in three ways.
They are as follows:

1. Inserting at Beginning of the list

2. Inserting at End of the list

3. Inserting at Specific location in the list

How to define self-referential structure?

It can be defined as: struct node

//structure definition of node

{ int info; struct

node *link; };
typedef struct node *NODE;

Here in the above structure we can see that keyword typedef the type “struct node *”
can also be written as NODE. So wherever we use struct node * can be replaced with
NODE.

NODE first; or struct node * first;

How to create empty list:

An empty list can be created by assigning NULL to a self-referential structure variable.

Eg: For example, consider the code struct node

{ int info; struct

node *link;

};

typedef struct node *NODE;

NODE first; //first is self-referential structure variable first=NULL;

//empty list by name first is created here

An empty list identified by the variable first is pictorially represented as:

NULL

first

Create a node:

How to create a node?

We can use malloc () function to allocate memory explicitly as and when required and
exact amount of memory space needed during execution. This can be done by:
x=(data_type *) malloc(size);
After doing the allocation, the function returns the address of 1st byte of allocated
memory. Since the address is returned, the return type is a void pointer. If the specified
memory is not available, then there will be condition called overflow of memory. In such
case functions returns NULL. So it is users responsibility to check whether there is a
sufficient memory.

if(x==NULL)

printf(“Insufficient memory\n”); exit(0);

If x is not null, it means a node is successfully created and we can return the node by the
statement return x;

C function to get a new node from the availability list:

NODE getnode()

NODE x; x=(NODE ) malloc (sizeof(struct node)); //allocate

memory space if(x==NULL) //free nodes does not exist

printf(“Out of memory\n”); //allocation failed terminate the program exit(0);

} return x; //allocation

successful }

Create a node with the specified item:

Step 1: get a node:


A node which is identified by variable first with 2 fields: info and link fields can be created
using getnode() function:

first = getnode();

first info first

link

Step 2: Store the item:

The data item 10 can be stored in the info field using the following statement:

firstinfo=10;

After executing above statement, the data item 10 is stored in info field of first

Step 3: Store NULL character:


After creating the node, if we donot want link field to contain address of any other node,
we can store \0(NULL) in link field as:

firstlink=NULL;
So by using above 3 steps we can create a node with specified data item as shown in
this figure:

Delete a node:

A node which is no longer used or required can be deleted using free() function as:

free(variable);

For eg: when above statement is executed, the memory space allocated for the node,
is deallocated and returned to OS so that it can be used by some other program. The
memory deallocated after executing:

free(first);

Operation on singly linked list:

1) Insert a node at the front end: Let us consider a linked list with 4 nodes. Here,
pointer variable first contains address of the first node of the list as:
Now let us try to insert the item 50 at the front end of the above list.

Step 1: Create a node using getnode() function as:

temp=getnode()

The pictorial representation is:

Step 2: Copy the item 50 into info field of temp using:

tempinfo=item;

The pictorial representation is:

Step 3: Copy the address of the first node of the list stored in pointer variable first into
link field of temp using:

templink=first;

Step 4: Now, a node temp has been already inserted and we can observe from figure
that temp is the first node. Let us return the address of the first node using:

return temp;
C function to insert an item at the front end of list:

NODE insert_front(int item, NODE first)

NODE temp;

temp=getnode(); //obtain a node from available list

tempinfo=item; //insert an item into new node

templink=first; //insert new node at the front of list return

temp; //return the new first node

Create a linked list:

Now let us see how to create linked list? So I is very simple call insert_front() function.

first=insert_front(item,first);

If first is NULL and item is 10, then above statement is executed, a linked list with only
one node is created as:

If the above statement is executed for 2nd time with item 20, a new node is inserted at
the front end and there by number of nodes in the list is 2:
If the above statement is executed for 3rd time with item 30, a new node is inserted at the
front end and there by number of nodes in the list is 3:

How to find address of last node in the list?

Consider the following singly list where the variable first contains the address of first
node of the list.

We need to find the address of the last node. So we have to start from the first node.
Instead of updating first, let us use another variable say current. The variable current
should contain the address of the first node. So this is done by writing statement:

cur=first;

cur=curlink;

After executing the above statement, current contains address of next node as:
cur=curlink

If we execute the instruction cur=curlink again, cur contains address of next node as:

If we execute the instruction cur=curlink again, cur contains address of next node as:

Here we can see current link is NULL then it denoted as it is last node of the list. If
cur contains address of first node, keep updating current as long as link field of
current is not NULL as: cur=curlink;  while(curlink!=NULL)

cur=curlink;

Now variable first contains address of the 1st node, we can find address of last node as:
cur=first; //find the address of last node of the list

while(curlink!=NULL)

cur=curlink;

How to find last node and last but one in the list:

Consider the following list: If current contains address of the 1st node of the list, what is
the previous node? The previous node does not exit and so we say previous is NULL.

The code can be written as:

prev=NULL;
cur=first;

Now we have to update current to get address of the last node. So the code can be
written as:

while(curlink!=NULL)

cur=curlink;

Now before updating cur inside the loop using cur=curlink. Let us copy cur to prev.
The code can be modified as:

while(curlink!=NULL)
{

prev=cur; cur=curlink;

So after the loop, the variable contains address of the last node and the variable
prev contains the address of the prev node. To find address of last node and last but
one node as: prev=NULL;

cur=first;

while(curlink!=NULL)

prev=cur; cur=curlink;

}
After above code is executed we get pictorial representation as this way:

Display singly linked list:

Case 1: List is empty: If the list is empty, it is not possible to display the contents of the
list. The code for this is:

if(first==NULL)

printf(“List is empty\n”); return;


}

Case 2: List is exiting: Consider the linked list with 4 nodes where the variable first
contains address of the first node of the list:

Initialization: We have to use another variable cur to point to the beginning of the list.
So this can be done by just copying first to cur as:

cur=first;

Display:

Now display the info field of cur node and update cur as:

printf(“%d”,curinfo); //output=20 cur=curlink;

//cur=1008

Now display info field of cur node and update cur as:
printf(“%d”,curinfo); //output=30 cur=curlink;

//cur=1048

Now display info field of cur node and update cur as:

printf(“%d”,curinfo); //output=10 cur=curlink;

//cur=1026

Now display info field of cur node and update cur as:

printf(“%d”,curinfo); //output=60 cur=curlink;

//cur=NULL

Finally, current is NULL so no more nodes to display. So these statements are


repeatedly executed as long as cur is not NULL. Once cur is NULL, the displaying of
node is finished.

printf(“%d”,curinfo);  while(cur!=NULL)

cur=curlink; {
printf(“%d”,curinfo);

cur=curlink;

C function to display the contents of linked list: void

display(NODE first)

NODE cur;

if(first==NULL)

printf(“List is empty\n”); return;

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

cur=first;

while(cur!=NULL)

printf(“%d”,curinfo);

cur=curlink;

Delete a node from the front end:

A node from the front end of list can be deleted by considering various cases
Case 1: List is empty: If the list is empty, it is not possible to delete a node from the list.
In such we have to display list is empty and return NULL.

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

printf(“List is empty\n”); return;

Case 2: List is exiting: Consider the list with 5 nodes where the variable first contains
address of the first node of the list.

We know the address of first node, now we need to know the address of the second
node of the list. Because after deleting the first node, the second node will be the first
node of the list. So these of steps we should follow when we delete a node.

Step 1: We have to use pointer variable temp and store the address of first node of the
list by the following statement:

temp=first;

Here temp and first points to first node

Step 2: Update the pointer temp so that variable temp contains the address of the
second node. So this can be achieved by the following statement:
temp=templink;

Now temp points to second node

Step 3: Here variable first points to first node of the list and temp points to the second
node of the list. Now display info field of the first node that have to be deleted and
deallocate the memory by using these statements:

printf(“item deleted=%d\n”,firstinfo); free(first);

After executing the above statement, the node pointed by first is deleted and is returned
to OS.

Step 4: Once the first node is deleted, we can observe that node temp is the first node.
So, return temp as the first node to the calling function using the statement:

return temp;

C function to delete an item from front end of the list:

NODE delete_front(NODE first)

NODE temp;

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

{
printf(“List is empty cannot delete\n”); return NULL;

//we can replace NULL with first also

temp=first; //retain the address of the node to be deleted

temp=templink; //obtain address of the second node printf(“item

deleted=%d\n”,firstinfo); //access the first node

free(first); //delete the front node return temp;

//return address of first node

Insert a node at rear end:


Step 1: First create a node using getnode() function then insert the item say 50 using
the following statements:

Step 2: If the list is empty, the above node can be returned as the first node of the list.
So this can be done by following statement:

if(first==NULL) return

temp;

Step 3: If the list is existing, we have to insert temp at the end of the list.
To insert at the end, we have to find address of the last node. So the code to find the
address of last node can be written as:

cur=first;

while(curlink!=NULL)

cur=curlink;

Step 4: Insert a node at the end: By looking the above list, we can easily insert temp

at the end of current. So this can be done by copying temp to curlink as:

curlink=temp;

Step 5: We can observe from the above list that first contains address of the first

node of the list. So we return first. return first;


C code to insert an item at rear end of the list:

NODE insert_rear(int item, NODE first)

NODE temp; //points to newly created node NODE

cur; //To hold the address of last node temp=getnode();

//obtain a new node and copy the item tempinfo=item;

templink=NULL;

if(first==NULL) //if list is empty return new node as the first node

return temp; cur=first; //if list exists, obtain address of last node

while(curlink!=NULL)

cur=curlink;

curlink=temp; //insert a node at the end return

first; //return address of first node

Delete a node from rear end:

Case 1: List is empty: If the list is empty, it is not possible to delete the contents of the
list. In such case we display appropriate message and return. The code is as follows:
if(first==NULL) //check for empty list

printf(“List is empty cannot delete\n”); return

NULL;

Case 2: List contains only 1 node: Consider s list with single node as:

Note: If link field of first contains NULL, it indicates that there is only one node.

If only one node is present, it can be deleted using free() function. Then we return

NULL indicating list is empty. So the code for this is: if(firstlink==NULL)

printf(“Item to be deleted is %d\n”,firstinfo);

free(first); //delete and return to OS return NULL;

//return empty list

Case 3: List contains more than one node: Consider the list with 5 nodes as:
Step 1: To delete the last node we should know the address of last node and last but
one node. For this, we have to use pointer variables, current and previous. Initially,
current points to the first node and previous points to NULL. So this can be written as:

prev=NULL;

cur=first;

Step 2: Now update current and previous so that current contains address of last
node and previous contains address of last but one node. This can be achieved by
following statements: while(curlink!=NULL)

prev=cur; cur=curlink;

After executing above loop, the variable current contains address of last node and
previous contains address of last but one node as:

Step 3: To delete the last node pointed to by current, the function free() is used.

printf(“Item deleted=%d\n”,curinfo); //item deleted=60 free(cur);

After executing above statements, the last node is deleted and the list is:
Step 4: Once the last node is deleted, the node pointed to by previous should be the last
node. This is achieved by just copying NULL to link field of previous as:

prevlink=NULL; //node pointed to by previous is the last node After

executing the above statements, the list can be shown as:

Step 5: Finally return address of first node return

first; //return address of first node

C function to delete a node from rear end of the list:

NODE delete_rear(NODE first)

NODE cur,prev;

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

{
printf(“List is empty cannot delete\n”); return

first;

}
if(firstlink==NULL)

printf(“Item to be deleted is %d\n”,firstinfo);

free(first); //return to availability list return NULL;

//list is empty so return NULL

//Obtain address of the last node and just previous to that prev=NULL;

cur=first;

while(curlink!=NULL)

prev=cur; cur=curlink;

printf(“Item deleted=%d\n”,curinfo); free(cur); //delete

the last node prevlink=NULL; //make last but one node as

the last node return first; //return address of first node

Write a C code for Searching in singly linked list:


#include<stdio.h>

#include<stdlib.h> void

create(int); void

search(); struct node

{ int data;

struct node *next;

};

struct node *head; void

main ()

int choice,item,loc;

do

printf("\n1.Create\n2.Search\n3.Exit\n4.Enter your choice?");

scanf("%d",&choice); switch(choice)

case 1: printf("\nEnter the item\n");

scanf("%d",&item);

create(item); break;

case 2:search(); case 3: exit(0);

break;
default: printf("\nPlease enter valid choice\n");

}while(choice != 3);

void create(int item)

struct node *ptr = (struct node *)malloc(sizeof(struct node *));

if(ptr == NULL)

printf("\nOVERFLOW\n");

else

ptr->data = item;

ptr->next = head; head =

ptr; printf("\nNode

inserted\n");

void search()
{
struct node *ptr;

int item,i=0,flag;

ptr = head; if(ptr

== NULL)

printf("\nEmpty List\n");

else

printf("\nEnter item which you want to search?\n");

scanf("%d",&item); while (ptr!=NULL)

if(ptr->data == item)

printf("item found at location %d ",i+1);

flag=0; } else {

flag=1; } i++;

ptr = ptr -> next;

if(flag==1)

{
printf("Item not found\n");

Circular linked list:

If link field of the last node contains starting address of first node. Such a list is called
circular list. In general, a circular list is a variation of ordinary linked list in which link
field of the last node contains address of the first node. This list is primarily used in
structures that allow access to nodes in the middle of the list without starting from the
first node.

The pictorial representation of a circular list is:

Advantages of circular list:

a) Every node is accessible from a given node by traversing successively using


the link field.

b) To delete a node current, the address of the first node is not necessary. Search
for the predecessor of node current, can be initiated from current itself.
c) Certain operations on circular list such as concatenation and splitting of list etc
will be more efficient.

The following 2 conventions can be used:

Approach 1
A pointer variable first can be used to designate the starting point of the list. Using this
approach, to get the address to get the address of last node, the entire list has to be
traversed from the first node.

Approach 2

In the second technique, a pointer variable last can be used to designate the last node
and the node that follow last, can be designated as the first node of the list.

The pictorial representation of the circular list is:

From the figure we can see that the variable last contains address of last node.
Using link field of last node that is lastlink, we can get address of the first node.

A circular list can be used as a stack or a queue. To implement these data structure, we
require of the following functions:

Insert_front: To insert an element at the front end of the list

Insert_rear: To insert an element at the rear end of the list

delete_front: To delete an element at the front end of the list

delete_rear: To delete an element at the rear end of the list display:

To display the contents of the list.

Insert at front end:

Consider a list with 4 nodes. Here, pointer last contains address of the last node of the
list. Let us try to insert an item at the front end of list.
Step 1: To insert an item 50 at the front of the list, obtain a free node using malloc()

function with the help of macro MALLOC() and insert the item using the statement:

MALLOC(temp,1,struct node); or temp=getnode(); tempinfo=item;

Step 2: Copy the address of the first node(i.e. lastlink) into link field of newly obtained
node temp and the statement is:

if(last!=NULL) templink=lastlink; else //if last is NULL, make

temp itself as the last node temp=last;

Step 3: Make temp as the first node. Establish a link between the node temp and the
last node. This is achieved by copying the address of the node temp into link field of
node last. The code can be written as:

lastlink=temp;
Step 4: Finally, we return address of the last node using the statement:

return last;

C function to insert an item at the front end of the list:

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

front end lastlink=temp; //link last node to

first node return last; //return the last node

Insert a node at rear node:

Let us consider a list with 4 nodes. Here, pointer last contains address of the last node
of the list. Let us insert an item 80 at the end of the list.

Step 1: Obtain a node using the function malloc() or getnode().

MALLOC(temp,1,struct node); or temp=getnode(); tempinfo=item;

Step 2: Copy the address of the first node (i.e. lastlink) into link field of newly obtained
node temp and the statement is:
if(last!=NULL) templink=lastlink; //copy the address of first node into link

field of temp else //if last is NULL, make temp itself as the last node

temp=last;

Step 3: Establish a link between the newly created node temp and the node last.
This is achieved by copying the address of the node temp into link field of node last.
The code for this is: lastlink=temp;

Step 4: The new node is made as the last node using:

return temp;

C function to insert an item at rear end of the list:

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 rear end lastlink=temp;

//link last node to first node return temp;

//make the new node as the last node

Delete a node from the front end:


Let us consider as a list with 5 nodes. Here, pointer last contains address of the last
node of the list. Let us delete an item at the front end of the list.

Step 1: In case if list is empty we cannot delete it So in this situation we can write code
as:

If list is empty: if(last==NULL)

{ printf(“list is

empty\n”); return

NULL;

In case we are deleting only one node, the list will be empty and we have to return
NULL. The code can be written as:

If there is only one node: if(lastlink==last) //in case

there is only node in the list

printf(“item deleted=%d\n”,lastinfo); //delete a node free(last);

return NULL; //return empty list

}
If there is more than one node:

first=lastlink; //obtain the address of the first node

Step 2: Make second node as first node. So this can be done by copying firstlink to
lastlink. The code can be written as:

lastlink= firstlink; //link the last node and new first node

Step 3: Now remove the first node by using free(). But before removing the node,
display appropriate message. The code can be written as:

printf(“the item deleted is %d\n”,firstinfo);

free(first); //delete the old first node

Now the node first is deleted. These steps have been designed by assuming the list is
already existing.

C function to delete an item from the front end:

NODE delete_front(NODE last)

{
NODE temp,first; if(last==NULL) //check

for empty list

printf(“List is empty\n”); return

NULL;

if(lastlink==last) //delete if only one node

{
printf(“the item deleted is %d\n”,lastinfo); //delete 50 element

free(last); return NULL;

first=lastlink; //obtain node to be deleted lastlink=firstlink;

//store new first node in link of last printf(“item deleted is

%d\n”,firstinfo); //delete the old first node free(first); //delete the

old first node return last; //return always address of last node

Delete a node from rear end:

Let us consider a list with 5 nodes. Here, pointer last contains address of the last node
of the list. Now let us delete an item at the rear end of the list.

Step 1:

In case if list is empty we cannot delete it So in this situation we can write code as:

If list is empty: if(last==NULL)

{ printf(“list is

empty\n”); return

NULL;
}

In case we are deleting only one node, the list will be empty and we have to return
NULL. The code can be written as:

If there is only one node: if(lastlink==last) //in case

there is only node in the list

printf(“item deleted=%d\n”,lastinfo); //delete a node free(last);

return NULL; //return empty list

}
Obtain the address of the predecessor of the node to be deleted. So this can be done
by traversing from the first node till the link field of a node contains address of the last
node. The code can be written as:

List with more than one node: prev=lastlink;

while(prevlink!=last) //find address of last but one node by updating prev as


long as prevlink is not last.

prev=prevlink;

Step 2: The first node and the last but one node (i.e. prev) are linked. So this can be
written as:

prevlink=lastlink;

Step 3: Remove the last node using free(). But before removing a node display
appropriate message. The code can be written as:
printf(“item deleted=%d\n”,lastinfo); free(last);

Step 4: Return prev itself as the first node of the result using the statement: return

prev;

C function to delete an item from rear end:

NODE delete_rear(NODE last)

NODE prev; if(last==NULL) //check

if list is empty { printf(“list is empty\n”); return

NULL;

if(lastlink==last) //delete if only one node

printf(“the item deleted is %d\n”,lastinfo);

free(last); return NULL;

prev=lastlink; //obtain address of previous node

while(prevlink!=last)

prev=prev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

C function to display the contents of circular queue: void

display(NODE last)

{
NODE temp; if(last==NULL) //check

for empty list

{ printf(“list is

empty\n”); return;

printf(“contents of the list are\n”); //display till we get last node

temp=lastlink; //get the address of first node while(temp!=last)

//traverse till the end

printf(“%d”,tempinfo); temp=templink;

printf(“%d\n”,tempinfo); //display last node


}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy