Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Ds Mod3

Download as pdf or txt
Download as pdf or txt
You are on page 1of 101

Module - 3

In this session, you will learn to:

Describe the limitations of using a data structure


such as an array

Define stack and heap variables


Describe the characteristics of stack and heap
variables

State the need for dynamic memory allocation


Use the malloc() function to allocate memory

Define self-referential structures and their


advantages
Array Usage – A Perspective

Consider the following example:


#include<stdio.h>
main( )
{
int num_array[50],i;
for( i=0; i < 50; i++ )
{
num_array[i]=0;
scanf( "%d",&num_array[i] );
fflush(stdin);
}
}
When this program is compiled, the compiler estimates
the amount of memory required for the variables, and also the
instructions defined by you as part of the program.

The compiler writes this information into the header of


the executable file that it creates. When the executable is
loaded into memory at runtime, the specified amount of
memory is set aside.

A part of the memory allocated to the program is in an


area of memory called a runtime stack or the call stack. Once
the size of the stack is fixed, it cannot be changed dynamically.
Memory minimization problem :
Therefore, arrays present the classic problem of
the programmer having allocated too few elements in the
array at the time of writing the program, and then finding at
run time that more values are required to be stored in the
array than what had originally been defined.

Memory Wastage :

The other extreme is of the programmer


allocating too many elements in the array and then finding at
run time that not many values need to be stored in the array
thereby resulting in wastage of precious memory.
Moreover, array manipulation (in terms of insertion and
deletion of elements from the array) is more complex and
tedious, and a better alternative to all this is to go for dynamic
data structures.

Before venturing into dynamic variables, or dynamic


data structures, it would be prudent at this juncture to
differentiate between stack and heap variables, and their
characteristics.

Let us begin by understanding the concept of lifetime of


variables.
Lifetime Of A Variable

• It is a run-time concept

• Period of time during which a variable has memory space


associated with it
begins when space is allocated
ends when space is de-allocated

• Three categories of "lifetime"


static - start to end of program execution
automatic (stack) - start to end of declaring function's
execution
heap (variable declared dynamic at runtime, and also de-
allocated dynamically at runtime).
Data Memory Model

static data
space for global variables

automatic data
run-time stack - activation records added
and removed as program runs (expands
and shrinks in an orderly LIFO manner)

space for variables allocated at run-


heap data time (allocation and de-allocation
requests occur in unpredictable order)
Heap Variables

Space for heap variables is allocated from an area of


runtime memory known as the heap or free store.

Heap variables do not have an explicit name, and are


accessed indirectly via a pointer.

Memory space for heap variables is explicitly allocated


at runtime using malloc( ).

Space occupied by heap variables must be explicitly


returned back to the heap to avoid memory leaks. This is done
using the free( ) function.
Dynamic Data Structures

Rather than pre-define array on the stack at compile


time, the alternative should be to define a structure type, and
dynamically declare at runtime as many instances of the
structure variables as needed by the application.

When the code containing the structure type is compiled,


what the compiler sees is only a structure type declaration. It
therefore, does not allocate memory for the structure type
since no variable has been defined based on the structure type.
Dynamic Data Structures

When the program begins execution, it will need to


create variables of the structure type. Therefore, the language
must support runtime declaration of variables.

The problem with these variables is that they cannot be


accommodated into the stack, as they were not declared at the
time of compilation, and the stack would have been sized
based on the stack variables already declared at compile-time.

The C language provides the malloc() function which a


program can use to declare variables dynamically.
Dynamic Data Structures

The parameter to malloc( ) is an unsigned integer which


represents the number of bytes that the programmer has
requested malloc( ) to allocate on the heap.

A more effective way of passing the number of bytes to


malloc( ) would be to pass the structure type along with the
sizeof( ) operator to malloc( ).

The sizeof( ) operator can be used to determine the size


of any data type in C, instead of manually determining the
size and using that value. Therefore, the benefit of using
sizeof( ) operator in any program makes it portable.
The malloc( ) Function
Consider the following example:
#include<stdio.h>
main()
{
struct marks_data
{
char name[11];
int marks;
};
struct marks_data *ptr;
/* declaration of a stack variable */

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

/* declaration of a block of memory on the heap and the block


in turn being referenced by ptr */
}
Linked Lists :
Definition :
A linked list is a data structure which is collection
of zero or more nodes, where each node has some information.
Each node is divided into two parts, the first part
contains the information of the element and the second part,
called the link.
Node

Address of next node

info link
Singly linked list :
A singly linked list is a linked list, where
each node has designated field called link field which contains
the address of the next node.
The below figure shows the representation of a singly
linked list consisting of the items 50,20,45,10 and 80.

1004 1020 1012 1008 1016


50 20 45 10 80 \0

first \0 first An empty linked list


The pointer first contains the address of the first node of
the list.
Defining a node :

Syntax :
struct node
{
type 1 info;
type 2 *link;
}

Note : Hear, struct is keyword and node is tagname.

The node consists of two fields info and link.


Info :
Since it contains the information, it can be of type int,
float, char, double.
eg: int info;
char info;

Link :
It contains address of the next node. So, link field must be
pointer to a node which can be declared as shown below,

struct node * link;


The structure definition of a node along with declaration can be
done as follows,
struct node
{
int info;
struct node * link;
};
typedef struct node * NODE;

A pointer variable first can be declared as shown below,


Method 1 : struct node * first;
or
Method 2 : NODE first;
The info and link field can be accessed using the
following notations,

Notation 1 : using * operator for Method 1


(* first).info
(* first).link

Notation 2 : using operator for Method 2

first info
first link
Now the question is where the nodes are present and
how to get these nodes.

Answer is “available list” and “getnode”.

Available list :
The list of free available nodes is called available list.
Avail

------------ \o
1000 1040 1020 1010
getnode :
The getnode() is a function which removes the first node
from the available list and makes it available for the user. The
getnode operation can be treated as a machine that
manufactures nodes. Each time the getnode is invoked, it gives
a new node from the available list.

Syntax :
Node first;
----------- ;
----------- ;
first = getnode();
The getnode () function is implemented based on whether the
available list is empty or not,

NODE getnode() // function - 1


{
Node x;
x = (NODE) malloc (sizeof(struct node));
// try to allocate requried size of memory.
if ( x == NULL )
{
printf ( “ out of memory” );
exit (0);
}
return x; // allocation successful and return the address.
}
Operations on singly linked list :

Insert a node at the front end :


To design the function let us follow the following
four steps,
Step 1 : Obtain a free node from the availability list and
identify the node with variable temp.
temp = getnode();
Step 2 : Copy item = 50 to the info field of temp
temp info = item ;
Step 3 : Attach pointer first to the link field of temp
temp link = first ;
Step 4 : Finally return the temp node.
return temp;
The below figure explains the above four steps,
• Before insertion :
first

20 45 10 80 \0
• Insertion steps :
4
• temp first

1 50 20 45 10 80 \0
2 3
first After insertion

50 20 45 10 80 \0
// function to insert a node

Node insert_front ( int item, NODE first )


{
NODE temp; // function 2.
temp = getnode ();
temp info = item;
temp link = first;
return temp;
}
Display linked list :
• As we know the first contains the address of the first node.
• To display the contents of the linked list we have to check list
is available or not.
• Consider the temp node and assign to first.
• By making temp = temp link we can display all the
contents, shown below.
first
1000 1004 1008 1012
20 45 10 80 \0

temp --------------------------------------
// function to display contents of list
void display (NODE first )
{
NODE temp; // function 3.
if ( first == NULL )
{
Printf (“ list is empty” ); return;
}
temp = first;
while ( temp != NULL )
{
printf ( “ %d “, temp info );
temp = temp link;
}
Delete a node from front end : The following steps will explain
the deletion of a node,

temp

1 20 45 10 80 \0

first i.e., temp = first ;

temp

2 20 45 10 80 \0

first temp = temp link;


Delete a node from front end : The following steps will explain
the deletion of a node,

4 temp

3 20 45 10 80 \0

first i.e., freenode ( first );


return ( temp );
After deletion :

45 10 80 \0

first
// function to delete a node
NODE delete_front ( NODE first )
{
NODE temp; // function 4
if ( first == NULL )
{
printf ( “list is empty” );
return first;
}
temp = first;
temp = temp link;
printf (“ item deleted = %d”, first info);
freenode (first);
return temp;
}
// Complete C – program
# include < stdio.h >
# include < alloc.h >
# include < process.h >

Strust node
{
int info;
struct node * link;
}; typedef struct node * NODE;
// function 1
// function 2
// function 3
// function 4
Void freenode ( NODE first )
{
free (first );
}
void main ()
{
Node first = NULL;
int choice, item;
for ( ; ; )
{
printf (“ 1.insert 2.delete 3.display 4.exit”);
printf ( “ enter your choice “);
scanf (“ %d”, & choice);
Switch ( choice )
{
case 1 : printf ( “ Enter the item to be inserted “ );
scanf ( “%d” , & item);
first = insert_front (item, first);
break;
case 2 : first = delete_front ( first );
break;
case 3 : display ( first );
break;
default : exit (0);
}
}
}
Insert a node at the rear end :
• Before insertion :
first temp

20 45 10 80 \0 55 \0

first temp

20 45 10 80 \0 55 \0

---------------------------------------
cur
Insert a node at the rear end :

first temp

20 45 10 80 \0 55 \0

cur link = temp; cur

• After insertion :
first

20 45 10 80 55 \0
// Algorithm to insert an item at the rear end of the list

Step 1 : Obtain a free node from the availability list and


identify the node with variable temp.
temp = getnode();

Step 2 : Copy item = 50 to the info field of temp and make link
field of temp to null.
temp info = item ; temp link = null;

Step 3 : Find the last node of a list. And insert it.

Step 4 : Finally return the first node.


return first;
// function to insert an item at the rear end of the list
NODE insert_rear ( int Item, NODE first )
{
NODE temp;
NODE cur;
temp = getnode();
temp info = item ;
temp link = NULL;
if (first == NULL ) return temp ;
cur = first ;
while ( cur link != NULL )
{
cur = cur link;
}
cur link = temp;
return first;
}
Delete a node at the rear end :
• Before deletion :
first

20 45 10 80 \0

First cur
-------------------------------------

20 45 10 80 \0

-------------------------
prev
first cur

20 45 10 80 \0

prev
freenode ( cur );
prev link = NULL;

After deletion :
first

20 45 10 \0
// function to delete an item at the rear end of the list
NODE delete_rear ( NODE first )
{
NODE prev;
NODE cur;
if ( first == NULL )
{
printf ( “ list is empty “ );
return first;
}
if ( first link == NULL )
{
printf (“ The item deleted is %d”, first info);
freenode ( first ); return NULL;
}
// Continued….
prev = NULL;
cur = first;
while ( cur link != NULL )
{
prev = cur;
cur = cur link;
}
printf ( “ The item deleted is %d”, cur info);
freenode ( cur );
prev link = NULL;
return first;
}
Creating an ordered linked list:
A linked list in which the items are stored in
some specific order is an Ordered linked list.
The elements in an ordered list can be in
ascending or descending order based on key information.

The following steps explains the creation of Ordered linked list.

Intially Ordered linked list looks as follows,

first

10 20 30 40 \0
Step 1:
Create a node to be inserted & insert the item information
Using the following statements,

temp = getnode();
temp -> info = item; 10 \0
temp -> link = NULL;

Step 2:
If the node temp is inserted into the list for the first time
(i.e, into the memory list) then return temp itself as the first
node using the following code.

if(first== Null) return temp;


Case1: Inserting an item at the front end of the list.
Step3:
Consider the list with 4 nodes having 10,20,30,&40 , as
the info of each node.
The item 5 is less than 10 which is the info of first node
of the list. To maintain the Order, the created node temp should
be inserted at the front of the list shown below,

first

10 20 30 40 \0
Step 4:
Once the node temp is inserted at the front end, let us return
temp indicating temp itself is the first node of the list using,
return temp;

temp first

10 10 20 30 40 \0

temp -> link = first;


return (temp);
Case 2: Insert an item at the middle /end:
Step 5: Finding appropriate position
The node temp containing item 35 should be inserted b/w two
nodes prev & cur as shown in fig.
first prev cur

10 20 30 40 \0

So,
Prev =Null; Cur= first; 35
While (cur! = Null && item > cur -> info)
{
Prev =cur;
Cur= cur-> link;
}
Step 6: Insert at middle/end;
prev-> link = temp;
temp-> link = cur;

Step7: Return first node;


Return first;
( cur = NULL )
first prev temp

10 20 30 40 50 \0
//C function to create an Ordered linked list.
NODE insert_ord (int item, NODE first)
{
NODE temp, prev, cur;
temp = getnode();
temp-> info=item; step 1
temp-> link=Null;
if (first==NULL) return temp; step 2
if(item < first-> info)
{
temp-> link = first; step 3 & 4
return temp;
}
Prev=NULL;
Cur=first;
While (cur!=NULL && item > cur-> info) step 5
{
prev=cur;
Cur=cur-> link;
}
prev-> link=temp; step 6
Temp->link=cur;
return first; step 7
}
*Search for an item in a list:
// Function to search for key in the list.

Void search (int key, NODE first)


{
NODE cur;

if(first==NULL)
{
Printf(“list is empty”);
Return;
}
Cur=first;
While (cur!=NULL)
{
If(key == cur-> info)
break;
cur = cur-> link;
}
if(cur== NULL)
{
printf(“search is unsuccessful’);
return;
}
printf(“search is successful’);
}
Delete a node at the specified position:
NODE delete_pos(int pos, NODE first)
{
NODE cur;
NODE Prev;
Int count;
If (first == NULL || pos <=0)
{ Printf (“Invalid position “);
Return NULL:
}
if (pos==1)
{ Cur=first;
first=first-> link;
freenode(cur);
return first;
}
prev =NULL;
Cur =first; Count=1;
While (cur !=NULL)
{
If (count== pos)
break;
prev =cur;
cur=cur-> link;
}
if (count! =pos)
{
printf(“Invalid Position”);
return first;
}
prev -> link = cur -> link;
freenode(cur);
return first;
}
Insert a node at the specified position.

Node insert-pos(int item ,int pos, NODE first)


{
NODE temp;
NODE Prev ,Cur;
int count;
temp= getnode();
temp-> info= item;
temp -> link =NULL;

If((first==NULL) && (pos==1))


return temp;
If(first== NULL)
{
Printf(“Invalid positon”);
return first;
}
If (pos==1)
{
temp-> link =first;
return temp;
}

Count =1;
prev=NULL:
cur=first;
While (cur!=NULL && count!=pos)
{
prev =cur;
cur=cur-> link;
Count ++;
}
If(count == pos)
{
Prev->link=temp;
Temp->link=cur;
Return first;
}
Printf(“Invalid position”);
Return first;
}
Concatenate two lists:
first * Before Concatenation

10 20 40 \0
second

10 20 40 \0

* After Concatenation
first cur

10 20 40 10 20 40 \0
// C function to concatenate two lists
NODE concat (NODE first, NODE second)
{
NODE cur;
if(first == NULL) return second;
if(second == NULL) return first;
cur=first;
While (cur-> link ! =null)
{
cur=cur-> link;
}
cur-> link = second ;
return first;
}
Header Node:

A header node in a linked list is a special node whose


link field always contains address of the first node of the list.

If list is empty , then link field of header node contains


\0(null).

Using header nodes, any node in the list can be accessed.

The info field of such a node usually does not contain


any information & such a node does not represent an item in
the list.
Header Node lists :
empty header node

\0

Singly linked list with header node

header node

20 30 40 \0
Circular list with a header node :
In a circular list with a header node, the link field
of the last node contains address of the header node & the link
field of the header node contains the address of the first node.

header node

20 30 40
Insert a node at the front :

Step1:
Obtain a new node
temp = getnode();
temp -> info=item;
Step2: Make a link to first node.
temp-> link = head-> link;
Step 3: Reassign the head pointer
head -> link = temp;
Step 4: Return the address of header,
return head;
Before insertion :
head * Before insertion

20 30 40

temp 1 * After insertion

10
head 3 2
4
20 30 40
// function to insert at the front end.

NODE insert_front ( int item, NODE head)


{
NODE temp;

temp= getnode();
temp->info=item;

temp-> link=head-> link;


head->link=temp;
return head;

}
Insert a node at the rear end:
head * Before insertion

20 30 40

* After insertion
head cur temp

20 30 40 50
// function to insert at the rear end of the list

NODE insert_rear(int item, NODE read)


{
NODE temp, cur;
temp= getnode();
temp-> info=item;
cur=head-> link;
While(cur-> link !=head)
{ cur = cur -> link
}
cur->link =temp;
temp-> link=head;
return head;
}
// Delete a node whose info field is specified:

NODE delete_item(int item, NODE head)


{
NODE prev,cur;
If (head-> link == head)
{
printf(“list is empty”);
return NULL;
}

prev = head;
cur = head->link;
// Delete a node whose info field is specified:
While(cur!=head)
{
if(item== cur->info) break;
prev=cur;
cur=cur->link;
}
if(cur==head)
{
printf(“item not found \n”); return head;
}
prev-> link=cur-> link;
freenode(cur);
return head;
}
Insert a node at the specified position :
head * Before insertion

20 30 40

* After insertion
head prev cur

20 30 40

50

temp
// Insert a node at the specified position :
NODE insert_position (int item, int pos, NODE head)
{
NODE Prev, cur, temp;
int i;
prev=head;
cur=head->link;
count=1;
Whil;e(cur!=head)
{
if(count==pos) Break;
prev=cur;
cur=cur->link;
count++;
}
// Insert a node at the specified position :

if(count!=pos)
{
printf(“invalid position”);
return head;
}
temp=getnode();
temp->info=item;
prev-> link=temp;
temp->link=cur;
return head;
}
Delete a node at the specified position :
head * Before delition

20 30 40

* After insertion
head prev cur

20 30 40

prev-> link = cur-> link;


freenode(cur);
// Delete a node at the specified position :

NODE delete_position (int pos, NODE head)


{
NODE prev,cur;
int i;

if(head-> link== head)


{
printf(“list is empty”);
return head;
}
// Delete a node at the specified position :

prev =head;
cur = head-> link;
count = 1;
While(cur!=head)
{
if(count ==pos)
break;
prev = cur;
cur = cur->link;
count++;
}
// Delete a node at the specified position :

if(count!=pos)
{
printf(“ Invalid positon”);
return head;
}
prev->link=cur-> link;
freenode(cur);
return head;
}
// Display the contents of circular list:
Void display (NODE head)
{ NODE temp;
if(head-> link == head)
{
printf(“List is empty”); return;
}
printf(“contents of the list is”);
temp = head->link;
While(temp!=head)
{
printf(“%d”,temp->info);
temp = temp->link;
}
}
//complete “c” program for circular linkedlist.
#include<stdio.h>
#include<alloc.h>
#include<process.h>

Struct node
{
int info;
Struct node * link;
};

typedef struct node* NODE;

/* include all the function discussed earlier*/


void main()
{
NODE head;
int choice, item,pos;

head=getnode();
head->info=0;
head->link=head;
for(;;)
{
printf(“1.Insert_front 2. Insert_at_postion”);
printf(“3.Delete_item 4.Delete_at_postion”);
printf(“5. Display 6.Exit”);
printf(“enter the choice”);
Scanf(“%d”, & choice);
Switch(choice)
{
Case1:
Printf(“enter the item to be inserted”);
Scanf(“%d”,&item);
head = insert_front(item,head);
break;
Case2 :
printf(“enter the item to be inserted”);
Scanf(“%d”,&item);
printf(“at position=”);
Scanf(“%d”, &pos);
head = insert_position(item,pos,head);
break;
Case3:
printf(“enter the item to be deleted”);
Scanf(“%d”,&item);
head = delete_item(item,head);
break;
Case4:
printf(“position of node to delete”);
Scanf(“%d”,&pos);
head = delete_position(pos,head);
break;
Case5:
display(head); break;
Default:
exit(0);
} }
Static allocation vs. Linked allocation
Static allocation technique Linked allocation technique
Memory is allocated during compilation time. Memory is allocated during execution time
The size of the memory to be allocated is fixed As & when memory is required, memory can
during compilation time & cab not be altered be allocated. If not required, memory can be
during execution time. deallocated. The size of the memory required
may vary during execution time.
used only when the data size is fixed & known used only for unpredictable memory
in advance before processing. requirement
Execution is faster, since memory is already Execution is slower since memory has to be
allocated & data manipulation is done on allocated during runtime. Data manipulation
these allocated memory locations. is done only after allocating the memory.
Memory is allocated either in stack area (for Memory is allocated only in heap area
local variables) or data area (for global &
static variable).
Data accessing is very fast & is done by Data accessing is very slow. Data stored in the
specifying the array name along with index. beginning of the list can be accessed very fast.
Time take to access a[0] & a[1000], in general But, to access any other data, the list has to be
a[i] is same. traversed & definitely requires more time.
Static allocation vs Linked allocation
Static allocation technique Linked allocation technique
It is difficult to insert or delete the data in The data can be inserted anywhere in the
the beginning or middle of the array. list. Addition or deleting of a node is done
First, we have to make a room by just by manipulating the links.
copying the items into successive locations
& then insert. While deleting an item, the
subsequent elements should be copied
into previous locations.
If we can predict the size of the data or if If the size of the data can not be
the size of the data is known in advance, predicted or number of items to be
then it is better to go for static allocation. inserted is not known in advance, then it
is better to go for linked allocation.

For n items only n memory locations are For n items, apart from n memory
allocated. locations extra memory required for each
node to store the address of the next
node. So, more memory space is used for
n items when compared with arrays.
DOUBLY LINKED LISTS:

A doubly-linked list is a linear collection of nodes where


each node is divided into three parts;

info : This is a field where the information has to be stored.


llink : This is a pointer field which contains address of the left
node or previous node in the list.
rlink : This is a pointer field which contains address of the right
node or next node in the list.

NODE

llink info rlink


Using such lists, it is possible to traverse the list in
forward & backward directions.

The doubly list is also called as two way list.

There are three different types of doubly linked list.

1. Regular Doubly Linked List


2. Circular Doubly Linked List
3. Circular Doubly Linked List with a header node.
All the three representation is shown below,
first * Regular DLL

\o 20 10 20 30 \0

* Circular DLL
first

20 10 20 30

Header node

10 20 30

Circular DLL with header node


Regular Doubly Linked List ( with initial header node ) :
To create a node:
Step1 : We have to assign NULL for header
i.e.; header -> left = header -> right = NULL;
\0 \0

step2 : Create new node & insert as first nod.


NODE newnode;
newnode -> info = x;
newnode -> right = header;
header = newnode;
header Insertion header After Insertion

\0 10 \0 10 \0
//To insert a node to Doubly Linked List based on position.

Step1:
Create a newnode & assign NULL to left & right pointer;
ie; NODE newnode;
newnode -> info = x;
newnode -> left = newnode -> right = NULL;

Step2:
Check for valid position.
ie; if ((Pos < 1) || (Pos > (size + 1)))
invalid position
free(newnode);
//To insert a node to Doubly Linked List based on position.

Step3:
Suppose position is equal to 1,

newnode -> right = header;


header -> left = newnode;
header = newnode;

header

header 10 \0
10 \0

\0 12 \0 12
newnode newnode
Step 4: Suppose position greater than 1.
Find the position & insert.
header

10 12 \0
newnode
\0 11 \0
* Insert at position 2

header
prev next

10 12 \0

newnode 11
Step4: Suppose position greater than 1.

Find the position & insert.

ie., next = header;

for(i = 1; i != Pos; i++)


next = next -> right;

prev = next -> left;


prev -> right = newnode;
newnode -> left = prev;
newnode -> right = next;
next -> left = newnode;
To delete a node from doubly linked list based on position.

Step1: Create some temporary nodes like Prev, Pres, & next
NODE Prev, Pres, next;
Prev = Pres = header;
Step2: Check for valid position
if(Pos < 1) || (Pos > size) || (header == NULL))
Invalid position;
Step3: If position is equal to 1
if(Pos == 1)
Header = header -> right;
header header

10 \0 \0 \0
Step4: If position is greater than 1. find position & delete

for(i = 1; i != Pos; i++)


{
Pres = Pres -> right;
}
Prev = Pres -> left;
Next = Pres -> right;
Prev -> right = next;
Next -> left = Prev;
Print(“The deleted element is”, Pres -> info);
freenode(Pres);
To display the contents of doubly linked list :

NODE temp;
temp = header;

if(header == NULL)
printf("List is empty“);

while(temp!=NULL)
{
printf(“temp->info”);
temp = temp->right;
}

** Complete program will be in word file.


Circular doubly linked list with a header node :

10 20 30
//C Function to insert a node at the front end of the list.
NODE insert_front(int item,NODE head)
{
NODE temp ,cur;
temp=getnode();
temp-> info=item;
cur=head->rlink;
head->rlink=temp;
temp->llink=head;
temp->rlink=cur;
cur-> llink=temp;
return head;
}
//C Function to insert a node at the end of the list.

NODE insert_rear(int item,NODE head)


{
NODE temp,cur;
temp=getnode();
temp->info=item;
cur=head->llink; // by using while loop find the position.
head->linl=temp;
temp->rlink=head;
temp->llink=cur;
cur->rlink=temp;
return head;
}
// Function to delete a node form the rear end
NODE delete_rear(NODE head)
{
NODE cur, prev;
if (head -> llink == head)
{
printf(“Deque is empty\n”);
return head;
}
cur = head -> link; /*obtain address of the last & last but one node*/
prev = cur -> llink;
head -> llink = prev; /* adjust links in both directions */
prev -> rlink = head;
printf(“the node to be deleted is %d\n”, cur -> info);
freenode(cur); /* delete the node */
return head;
}
// Function to delete a node whose info is provided:
NODE delete_item(int item, NODE head)
{
NODE prev, cur, next;
if( head -> rlink == head)
{
printf(“List is empty\n”);
return head;
}

cur = head -> rlink; /* find the address of node to be deleted */

while( cur != head)


{
if(item == cur -> info) break;
cur = cur -> rlink;
}
// Function to delete all nodes whose info is same as key item
NODE delete_all(int item, NODE head)
{
NODE prev, cur, next;
int count;
if( head -> rlink == head )
{
printf(“List is empty\n”);
return head;
}
count = 0; /* assume key initially not present */
cur = head -> rlink; /* find the address of node to be deleted */

while( cur != head )


{
if(item != cur -> info)
cur = cur -> rlink;
// Function to delete all nodes whose info is same as key item
else
{
count++; /*update the number of occurrences*/
prev = cur -> llink; /* obtain the address of the predecessor */
next = cur -> rlink; /* obtain the address of the successor */
prev -> rlink = next; /* adjust the pointers & delete the node */
next -> llink = prev;
freenode(cur);
cur = next; /* search for key from this point */
}
}
if(count == 0 )
printf(“Key not found\n”);
else
printf(“Key found at %d positions & are deleted\n”,count);
return head;
}
Singly Vs Doubly linked lists :

Singly linked list Doubly linked list


Traversing is only in one direction Traversing can be done in both
directions
while deleting a node, its predecessor while deleting a node x, it predecessor
is required & can be found only after can be obtained using llink of node x,
traversing from the beginning of list No need to traverse the list.

occupy less memory Occupy more memory

programs will be length & need more using circular linked list with header,
time to design efficient & small programs can be
written & hence design is easier.

care is taken to modify only one link care is taken to modify both links of a
of a node node.

You might also like