0% found this document useful (0 votes)
6 views46 pages

Linked List

This document discusses pointers in C programming. It begins by explaining that a pointer is a variable that stores the address of another variable. It then covers pointer declaration syntax, using the address operator to assign a pointer variable to the address of another variable, and how pointer variables allow changing the value of another variable indirectly. The document also notes that all pointers require the same amount of memory regardless of the type of data being pointed to, as pointers only store addresses. Finally, it briefly introduces calling functions by value versus by reference using pointers.

Uploaded by

Ahalya M
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
6 views46 pages

Linked List

This document discusses pointers in C programming. It begins by explaining that a pointer is a variable that stores the address of another variable. It then covers pointer declaration syntax, using the address operator to assign a pointer variable to the address of another variable, and how pointer variables allow changing the value of another variable indirectly. The document also notes that all pointers require the same amount of memory regardless of the type of data being pointed to, as pointers only store addresses. Finally, it briefly introduces calling functions by value versus by reference using pointers.

Uploaded by

Ahalya M
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 46

Linked List

4.1 INTRODUCTION TO POINTERS

Any variable, which is declared and initialized, has three things associated
with it

1. A memory location with to hold the value of the variable,


2. The initialized value, which is stored in the location and
3. The address of that memory location.

All the three things are equally important. The name of a variable, which
represents the memory location, is used to output the value stored in the variable and
the address of the variable is used to input a value to the variable.

a Name

5 Value

1000 Address

Figure 4.1 Components associated with a variable

We have always used variables to store values, however a variable can also be
used to store the address of another variable such variables are termed as pointer
variables. Thus a pointer is a variable, which can contain the address of another variable.
The program below highlights this fact very clearly.
Linked List
2
Program 4.1: To show the creation of a pointer variable.

#include <stdio.h>
void main( )
{
int a = 9;
int *b;

b = &a;

printf( “ Address of the variable a = %u \n”, &a);


printf( “ Value of the variable a = %d \n”, a);
printf( “ Address present in the variable b = %u \n”, b);
}

OUTPUT
Address of the variable a = 1736
Value of the variable a = 9
Address present in the variable b = 1736

Observing the program closely highlights the following points:

1. The address of a variable is accessed with the help of the “&” operator.
2. Using the name of the variable we can accesses the value of a variable.
3. A pointer variable is created by including the operator “*” when the variable is
declared.
4. A pointer variable can hold only the address of another variable and not the
value of another variable.

4.2 POINTER DECLARATION

We have already seen the use of a pointer and its usage, in this section we try to
understand all the concepts clearly. A pointer is a variable that contains the address of
the memory location of another variable. To create a pointer variable we use the syntax
as shown in the Figure below. First we will have to specify the type of data stored in the
location identified by the pointer. Then a variable is created along with an asterisk. The
asterisk tells the compiler that you are creating a pointer variable. Finally, you give the
name of the variable.

Variable type being pointed to pointer variable name

Data type *variable_name;

A asterisk denotes a pointer

4.3 POINTER OPERATOR

A pointer operator is used to classify a variable as a pointer and not as a normal


variable. Pointer variables can only store the address of another memory location, while
Linked List
3
a normal variable can only store a value and not an address. The classification is done
by representing the variable with a combination of *(asterisk) with the variable name.

For example:
int *ptr;

The base type of the pointer defines which type of variables the pointer is pointing
to. Technically, any type of operator can point anywhere in memory. All pointer arithmetic
is done relative to its base type. So it is important to declare the pointers correctly.

4.4 ADDRESS OPERATOR

Once we declare a pointer variable, we must make it to point to something. We can do


this by assigning to the pointer the address of the variable you want to point to as in:

ptr = &num;

This places the memory address of the variable num into the pointer variable ptr. If
num is stored in memory 1765 address, then the variable ptr has the value 1765. The
figure below highlights the situation discussed above.

Memory Address Memory Address


of num 1765 2150 of ptr

Contents of
45 1765
pointer
num ptr

Figure4.2 Allocation of address to pointer variable

NOTE
We can also assign an address to the variable ptr directly. Thus the instruction
ptr = 1765;

Would generate a compiler error because it is attempting to assign an integer value to


the pointer. The only assignment you can make to the variable ptr is the address of a
variable, using the address operator, as

ptr = &num;

However, we can assign a value to the pointer *ptr, as in

*ptr = 45;

This means “ Place the value 45 in the memory address pointed by the variable
ptr.” Since the pointer contains the address 1765, the value 45 is placed in that memory
location. And since this is the location of the variable num, the value of num is also
becomes 45. This shows how we can change the value of a variable indirectly using a
pointer and the indirection operator.
Linked List
4
Program 4.2: To display the contents of the variable and their address using a pointer
variable.

#include <stdio.h>
void main( )
{
int num,*int_ptr;
float x,*float_ptr;
char ch, *char_ptr;

num=123; x=12.34; ch=’A’;


int_ptr = &num; float_ptr = &x; char_ptr = &ch;
printf(“Num %d is stored at the address %u\n”, *int_ptr ,int_ptr);
printf(“Float %f is stored at the address %u\n”,*float_ptr, float_ptr);
printf(“Character %c is stored at the address %u\n”,*char_ptr,char_ptr);
}

OUTPUT
Num 123 stored at the address 65524
Value 12.340000000 stored at the address 65520
Character A stored at the address 65519

4.5 SPACE REQUIRED FOR POINTER VARIABLES

The amount of memory space allotted when a variable is created and compiled
depends on the data type of the variable. The amount of space reserved for a variable
has already been explained in the previous section. In this section we try to understand
how much space will be allotted to a pointer variable of different types of data. The
program below highlights this point clearly.

Program 4.3: To show the amount of space required to store variables and space
reserved for pointers.

#include <stdio.h>
void main( )
{
int a = 5, *int_ptr;
char b = ‘w’, *char_ptr;
float c = 17.53, *float_ptr;

int_ptr = &a; float_ptr = &b; char_ptr = &c;

printf( “ Value of integer = %d \n”, a);


printf( “ Value of char = %c \n”, b);
printf( “ Value of float = %f \n”, c);
printf( “Amount of space for int ptr = %u bytes \n”, sizeof(int_ptr));
printf( “Amount of space for char ptr = %u bytes \n”, sizeof(char_ptr));
printf( “Amount of space for float ptr = %u bytes \n”, sizeof(float_ptr));
}
Linked List
5
OUTPUT
Value of integer = 5
Value of char = w
Value of float = 17.530000
Amount of space for int ptr = 2 bytes
Amount of space for char ptr = 2 bytes
Amount of space for float ptr = 2 bytes

What is observed from the above-described fact is a very important fact. The
amount of space to store different variables may vary. However the size of all the addresses
available is the same and depends on the word length of the computer being used. Thus
we observe that all the outputs are the same i.e., a pointer is created to hold the address
of another memory location and the size of the address is the same immaterial of the
type of data it holds, thus the outputs are the same.

4.6 POINTERS AND FUNCTIONS

Pointers are used very much with functions. Also sometimes complex function
can easily be represented and accessed only with a pointer. Arguments can be passed to
one of the following methods.

a. Passing values of the arguments (Call by Value)


b. Passing the addresses of the arguments (Call by Reference)

4.6.1 CALL BY VALUE

We have seen that when a function is invoked, a correspondence is established


between the formal and actual parameters. A temporary storage is created where the
value of the actual parameter is stored. The formal parameter picks up its value from
this storage area. This mechanism of data transfer, between the actual and formal
parameters, allows the actual parameters to be an expression, functions, arrays, etc.
Such parameter is called Value parameters and mechanism of data transfer is referred
to as Call-By-Value. The corresponding formal parameter represents a local variable in
the called function. The current value of the corresponding actual parameter becomes
the initial value of the formal parameter. The value of formal parameter may then
change in the body of the subprogram by assignment or input statements. This will not
change the value of the actual parameter.

4.6.2 CALL BY REFERENCE

Whenever a function call is made if we pass the address of a variable to a function,


the parameters receiving the address should be pointers. The process of calling a function
using pointers to pass the address of variable is known as Call-By-Reference. The
function, which is called by ‘reference’, can change the value of the variable used in the
call i.e., any changes made to the copied variables will affect the original variables also.

Program 4.4 : To exchange the contents of the two variables using call by value and call
by reference.
Linked List
6
#include <stdio.h>
void main( )
{
int a,b;
void swap_val(int , int );
void swap_ref(int *, int * );

printf(“Enter two numbers \n “);


scanf(“%d %d”,&a,&b);
printf(“a =%d b = %d before function \n “,a,b);
swap_val(a,b);
printf(“a =%d b = %d after function call using call by value \n “,a,b);
swap_ref(&a,&b);
printf(“a =%d b = %d after function call using call by reference \n “,a,b);
}

/* Function to exchange two values using call by value */


void swap_val(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}

/* Function to exchange two values using call by reference */


void swap_ref(int *x, int * y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}

4.7 POINTERS AND STRUCTURES

So far, it has been seen that a member of a structure could be an ordinary data
type such as int, float, char and even a structure also. In C, it is permitted to declare a
pointer as a member to a structure. A pointer can be used to hold the address of structure
variable. The pointer variable with structure can be used to construct a complex data
structures such as linked lists, doubly linked lists, binary tree etc.

Example: The following declaration illustrates use of pointers with structures.

struct complex
{
float real;
float imag;
};
Linked List
7
struct complex *ptrc1;

Where ptrc1 is a pointer variable holding the address of the structure complex
and is having two members, real of type float and imag of type float. Values can be
assigned to individual elements of a structure using the following method.

Method structure name-> field name = variable ;

Program 4.5: To illustrate the use of pointers with structures.

#include <stdio.h>
void main( )
{
struct complex
{
float *real;
float *imagi;
};
struct complex *c1;
struct complex *c1;
float real_part,imagi_part;

real_part = 34;
imagi_part = 77;
c1->real = &re;
c1->imagi = &imagi;
printf(“Content of the real part : %.2f”,*c1->real);
printf(“Content of the imaginary part : %.2f”,*c1->imagi);
}

OUTPUT
Content of the real part : 34
Content of the imaginary part : 77

4.8 DYNAMIC MEMORY ALLOCATION

Consider the following array declaration,


int a[10][10];

This type of declaration would be generally used to write a generalized program


to perform operations on matrices. The moment the declaration is made the system
reserves a total of 100 locations each of two bytes for the array. However when we are
running the program we may enter a matrix of just three rows and three columns. This
results in wastage of space of 91 memory locations. This method of allocating space
when the variable is created is called as static allocation of space.

Another possibility is to allocate as much space as required when running the


program. This method of allocating space while running the program is called as dynamic
Linked List
8
allocation of space. This above said possibility can be achieved with the help of the
standard library functions malloc( ) and calloc( ).

The definitions for the library functions malloc( ) and calloc( ) is present in the
header file “alloc,h”. malloc( ) and calloc( ) are similar in their works. However they
differ in two important aspects. The function malloc( ) needs one argument which identifies
the total space to be reserved and the function calloc( ) requires two arguments the first
argument identifies the total locations required and the second argument identifies the
space required for each location.

Another difference between the functions malloc( ) and calloc( ) is that the memory
space created with malloc( ) contains garbage values whereas the memory space created
with calloc( ) is initialized to zeros if it points to an integer and blank spaces if it points
to a character.

Program 4.6: To show the use of dynamic allocation of space

#include <stdio.h>
#include “alloc.h”
#include <stdlib.h>
void main( )
{
int n,*p, i ,s=0;
float avg;

printf(“How many numbers \n”);


scanf(“%d”,&n);

p = (int *) malloc( n * sizeof(int));

if ( p== NULL)
{
printf(“ Memory allocation unsuccessfull\n”);
exit();
}
printf(“ Enter %d numbers \n”,n);
for ( i=0 ; i<n ; i++)
scanf(“%d”, ( p + i ));

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


s = s + *(p + i );
avg = (float) s / n;

printf(“The numbers are \n”);


for ( i=0 ; i<n ; i++)
printf(“%d\t”, *( p + i ));
printf(“\nThe average = %f\n”,avg);
}
Linked List
9
OUTPUT
How many numbers
5
Enter 5 numbers
1 2 3 4 5
The numbers are
1 2 3 4 5
The average = 3.000000

4.9 INTRODUCTION TO LINKED LIST

Whenever we go to the departmental store we carry a list along with us. The list
usually contains a list of items arranged in order indicating the items of our requirement.
Many problems in computing also involve lists of items. A list is a data type, which
contains elements of the same type arranged in a set of continuous memory locations.
With lists it is possible for us to perform certain operations such as searching the list,
sorting it, printing it, and so on. The structure we have used as the concrete data
representation of a list is the array, which is a sequential structure.

Operations such as searching can be very efficiently carried out using an array
representation. However, inserting and deleting items cannot be easily performed with
an array representation. To insert a new item into a location in a list, we must shift the
array elements down to make room for the new item. Similarly, deleting an item from
the list requires that we shift up all the array elements following the one to be deleted.

Another drawback with arrays is that they are not very adaptable since the size
of the array must be fixed in advance. The size of the array cannot be increased or
decreased during the execution of the program. These problems can be overcome by
considering another data structure called - the linked list.

4.10 LINKED LIST

A linked list represents a linear collection of items, called as nodes. Nodes of a linked
list can be scattered about in the memory, they need not necessarily represent a set of
consecutive memory locations. Each node in a linked list has two parts:

1. Information part, which contains the data for the node.


2. Link part, which gives the memory address of the next node in the list.

INFO LINK
NODE

3 5 7 NULL

Figure 4.3 Linked list with three nodes


Linked List
10
The Figure shows an abstract representation of a linked list. Information part
may consist of one or more fields. A linked list thus consists of a series of structures,
which are not necessarily contiguous. Each structure contains an information field and
a link, which is a pointer to the next structure, which is its successor. An arrow is used
in the link member of each node to indicate the location of the next node. The NULL in
the link member of the last node signifies the end of the list.

4.11 SINGLY LINKED LIST

A linked list in its simplest form is a collection of nodes that together form a
linear ordering. The ordering is determined as in the children’s game “Follow the leader,”
in that each node usually consists of a structure that includes information fields and a
link pointer. A singly linked list looks like that shown in the Figure.
HEAD

3 5 7 NULL

Figure 4.4 Linked list representation

The Figure shows a list of numbers, which is represented, in the form of a linked
list. HEAD is a pointer, which gives the address of the first node in the linked list. Link
field of the last node contains the NULL, which indicates it does not contain any address.

It might seem like circular reasoning to have a node reference another node, but
such a scheme easily works. The next reference inside a node can be viewed as a link or
pointer to another node. Likewise, moving from one node to another by following a next
reference is known as link hopping or pointer hopping. The first and last node of a
linked list usually is called the HEAD and TAIL of the list, respectively. We identify the
tail as the node having a NULL next reference, which indicates the termination of the
list. A linked list defined in this way is known as a singly linked list.

We have seen that a linked list is a collection of nodes of the same type and
hence and it can be defined as follows:

struct Node
{
Data type Information; INFO LINK
struct Node *Link;
}; NODE

Definition of a NODE of a Linked list in C

Once the structure of a node is defined we may want to allocate memory space
for the nodes of the linked list. Memory space is always allocated with the help of a
declaration statement. If we want to create a linked list that contains three nodes called
Node1, Node2 and Node3 the declaration may be as follows.
Linked List
11

struct node *Node1,*Node2,*Node3;

Program 4.7: A program to create a linked list which contains three nodes.

#include <stdio.h>
struct Node
{
int info;
struct Node *link;
};

void main( )
{
struct Node *Node1, *Node2, *Node3;

Node1->info=123;
Node1->link=Node2;
Node2->info=456;
Node2->link=Node3;
Node3->info=789;
Node3->link=NULL;
printf(“\nLinked list is \n”);
printf(“%d\t%d\t%d\t NULL”,Node1->info,Node2->info,Node3->info);
}

OUTPUT
123 456 789 NULL

4.12 DIFFERENT OPERATIONS POSSIBLE ON A LINKED LIST

1. Creating a linked list.


2. Traversing a linked list.
3. Inserting an item into a linked list.
4. Deleting an item from the linked list.
5. Searching an item in a linked list.
6. Merging two or more lists to form a single list.

We shall look into some of the important operations.

4.12.1 CREATING A LINKED LIST

Using the above program we were able to create a linked list, which contains
three nodes. There are some situations where we do not know how many elements are
to be inserted in a linked list. In such a situation we will have to use an alternative
technique in which the list components are dynamically created only as they are needed.

These dynamic nodes are created by using pointers and dynamic memory
allocation function such as malloc( ). We start accessing the list with a pointer variable
Linked List
12
that holds the address of the first node in the list. This pointer variable is named as
HEAD. Every node after the first node can be accessed by using the link member in the
previous node.

Such a list can expand or contrast as the program executes. To insert a new item
into the list, we allocate more space. To delete an item, we de-allocate the memory
assigned to it. We don’t have to know in advance how long the list will be. The only
limitation is the amount of available memory space. Data structures built using this
technique are called dynamic data structures.

To create a dynamic linked list, we begin by initializing the header HEAD to


NULL. We then create the first node and then assign its address to the header HEAD.
We then allocate a second node and store its address in the link part of the first node.
We continue this process of allocating a new node and storing the pointer to it into the
link part of the previous node the user decides to stop the process.

We would like to generalize this algorithm so that we can use a loop to create a
dynamic linked list of any length. General algorithm for creating a linked list is given
below.
ALGORITHM 4.1:

Step 1 : [ Initialize the header ]


HEAD = NULL
Step 2 : [Create a new node and store its address in the pointer NewNode]
NewNode = Address of new node
Step 3 : [Copy the information for the new node to the information part]
INFO[NewNode] = element
Step 4 : [Set the contents of the link part as NULL]
LINK[NewNode] = NULL
Step 5 : [Is the new node the first node ?]
If answer is yes Then
[Connect the new node to the header ]
HEAD = NewNode
Else
(a) [Take the CurrPtr to the last node of the linked list]
CurrPtr = Address of the last node
(b) [Connect the new node to the link of the last node]
LINK[CurrPtr] = NewNode
(c) Exit
[ Endif ]
Step 5 : Return

In the above algorithm, we used three pointers:

1. HEAD is used to hold the address of the first node of the linked list.
2. NewNode is used to hold the address of the new node.
3. CurrPtr, which is updated to always point to the last node in the linked
list.
Linked List
13
Program 4.8: Program to create a linked list.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;

void Create_link_list(int);
void Display(NODE *);

void main()
{
int ele;
char ch;

clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);
getch();
}

/* Function to add a node to the linked list */


void Create_link_list(int ele)
{
NODE *NewNode,*CurrPtr;

NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
NewNode->link=NULL;

if( HEAD==NULL)
HEAD=NewNode;
Linked List
14
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;

CurrPtr->link=NewNode;
}

}
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}

OUTPUT
Linked list creation
Enter information field of the node 56
Do you wish to enter one more node ? y
Enter information field of the node 89
Do you wish to enter one more node ? y
Enter information field of the node 23
Do you wish to enter one more node ?n
Linked list elements
56 89 23 NULL

Let us go through some of the statements, describing in words what is happening


and showing the linked list as it appears after the execution of the statement.
HEAD
HEAD = NULL;
NULL

The statement is used to initialize the header to NULL, which indicates that the
linked list has not yet been created.

NewNode = (NODE *)malloc(sizeof(NODE));


HEAD
NULL
NewNode
Linked List
15
A dynamic variable of type NODE is created. This statement obtains a piece of
memory to store a node and assigns its address to the pointer variable NewNode.
HEAD
NewNode->info = ele;
NewNode->link=NULL; NULL 3 NULL
NewNode

Using the above statements, the contents of the new node are entered.
HEAD
HEAD = NewNode;

3 NULL
NewNode
Connects the first node to the header pointer

CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr
HEAD

3 5 NULL 7 NULL
NewNode
The looping statement takes the CurrPtr from the first node to the last node of
the linked list.
CurrPtr->link=NewNode;
CurrPtr
HEAD

3 5 7 NULL

The pointer to the new node is copied into the link member of CurrPtr, which
connects the newnode to the linked list.

4.12.2 TRAVERSING A LINKED LIST

Traversing is the process of visiting each node of the linked list exactly once to
perform some operation. Our aim is to traverse the list starting from the first node to
the end of the list. Let LIST be a linked list with nodes containing two fields INFO and
LINK. HEAD is a pointer variable, which contains the address of the first node in the
linked list. CurrPtr is a pointer variable, which points to the node currently being
processed. The fields of the node is referenced by INFO[CurrPtr] indicates information
field of the node which has the address stored in CurrPtr variable. LINK[CurrPtr] is the
link field of the node which has the address stored in CurrPtr variable. The statement
Linked List
16

CurrPtr = LINK[CurrPtr]

moves the pointer to the next node in the list as illustrated in the figure below.
ALGORITHM 4.2:

This algorithm traverses a linked list by applying a process to each element of the list.
The variable CurrPtr points to the node currently being processed.

Step 1 : [ Initialize pointer variable CurrPtr]


CurrPtr = HEAD
Step 2 : [ Perform the traversing Operation ]
While CurrPtr != NULL Do
Step 3 : Apply PROCESS to INFO[CurrPtr]
Step 4 : [ Move pointer to next node ]
CurrPtr = LINK[CurrPtr]
[End of While Operation]
Step 5 : Exit

Example: Printing all the elements of the linked list is an example of traversing a
linked list. Here 3,5,7 is printed.

CurrPtr

HEAD

3 5 7 NULL

Figure 4.5 Traversing a linked list


Function to perform traversing
void Display(NODE *CurrPtr)
{
while(CurrPtr != NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“ NULL\n”);
}

To print the components of a linked list, we need to access the nodes one at a
time. This requirement implies an event controlled loop such as while should be used.
The event that stops the loop is reaching the end of the list. The loop control variable i.e.
CurrPtr is a pointer that is initialized to first node whose address is passed as an
argument to the function and is the advanced from one node to another by copying the
the link member of the current node. When the loop control pointer equals NULL, the
last node has been accessed.
Linked List
17
Let us do a code walk-through using the following list.
CurrPtr
CurrPtr=HEAD;
HEAD

3 5 7 NULL

CurrPtr and head both point to the first node in the list.

while(CurrPtr!=NULL) The loop is entered because CurrPtr is not NULL.

printf(“%d\t”,CurrPtr->info); CurrPtr
CurrPtr=CurrPtr->link;
HEAD

3 5 7 NULL

The number 3 is printed. CurrPtr now points to the second node in the list.

while(CurrPtr!=NULL) The loop is repeated because CurrPtr is not NULL.

printf(“%d\t”,CurrPtr->info); CurrPtr
CurrPtr=CurrPtr->link;
HEAD

3 5 7 NULL

The number 5 is printed. CurrPtr now points to the third node in the list.

while(CurrPtr!=NULL) The loop is repeated because CurrPtr is not NULL.

printf(“%d\t”,CurrPtr->info); CurrPtr
CurrPtr=CurrPtr->link; NULL
HEAD

3 5 7 NULL

The number 7 is printed. CurrPtr now contains NULL.


while(CurrPtr!=NULL) The loop is not repeated because CurrPtr is NULL.
Linked List
18
Program 4.9: Program to illustrate traversing operation in which find the largest element
in a linked list.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;

void Create_link_list(int);
void Display(NODE *);
int Largest (NODE *);

void main( )
{
int ele;
char ch;

clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);
printf(“\nLargest element in the list is %d”,Largest(HEAD));

getch();
}

/* Function to add a node to the linked list */


void Create_link_list(int ele)
{
NODE *NewNode,*CurrPtr;

NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
Linked List
19
NewNode->link=NULL;
if( HEAD==NULL)
HEAD=NewNode;
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;

CurrPtr->link=NewNode;
}

}
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}

/* Function to find the largest element in a linked list */


int Largest (NODE *CurrPtr)
{
int big = CurrPtr->info; /* First node information */
CurrPtr=CurrPtr->link; /* Move pointer to next node */
while(CurrPtr != NULL)
{
if(big < CurrPtr->info) big=CurrPtr->info;
CurrPtr=CurrPtr->link;
}
return big;
}

OUTPUT

Linked list creation


Enter information field of the node 56
Do you wish to enter one more node ? y
Enter information field of the node 89
Do you wish to enter one more node ? y
Enter information field of the node 23
Do you wish to enter one more node ?n
Linked list elements
56 89 23 NULL
Largest element in the list is 89
Linked List
20
4.12.3 MEMORY ALLOCATION

The maintenance of linked list in memory assumes the possibility of inserting


new nodes into the lists and hence requires some mechanism, which provides memory
space for the new nodes. Analogously, some mechanism is required where by the memory
space of deleted nodes becomes available for future use. Together with linked lists in
memory, a special list is maintained which consists of unused memory cells. This list,
which has its own pointer, is called the list of available space (AVAILABILITY LIST) or
free-storage list or free pool. The AVAIL pointer points to the first node in the availability
list.
AVAIL

NULL

Figure 4.6 Available linked list (Free storage linked list)

Whenever a node is to be inserted into a linked list, it is necessary to have a


function (GetNode) that supplies an unused node from the availability list. If there is a
free node, then the address of the available free node in which the new data can be
placed is also to be determined. We call this function as GetNode(). The following C
function will allocate a free node and makes it available to the program.

Function to create a node from the available list

NODE *GetNode()
{
NODE *NewNode;

NewNode = (NODE *)malloc(sizeof(NODE));


if ( NewNode == NULL)
{
printf(“Empty list!”); /* Free node is not available */
exit( 0 );
}
return NewNode; /* Return NewNode address to program */
}

The variable pointer NewNode points to the free node. Using malloc() function
we can allocate a free node and the address of the free node will be assigned to NewNode
pointer. If free node is not available the function malloc() returns NULL value and
assigned to NewNode pointer. This means that all the nodes are currently in use and it
is impossible to allocate any more. If a program calls on GetNode() function when the
available list is empty, the amount of storage assigned for the program’s data structure
is too small. Therefore, overflow occurs.
Linked List
21
4.12.4 INSERTING AN ITEM INTO A LINKED LIST

There are many applications where it is desired to maintain an order linear list.
The ordering may be in increasing order or decreasing order of information field. Such
an ordering often results more efficient processes in many cases. Before inserting a new
node, first we have to take the free node from the available list. If no free nodes are
available then we cannot insert the node. There are different types of insertions.

1. Insert a Node at the beginning of the linked list.


2. Insert a Node at the end of the linked list.
3. Insert a Node at a given position in the list

4.12.4.1 INSERT A NODE AT THE BEGINNING OF THE LINKED LIST

Let the HEAD pointer hold the address of the first node of the linked list. The
following algorithm will create a new node and insert this node at the beginning of the
linked list.

ALGORITHM 4.3:

Let LIST be a list stored in memory, HEAD gives the address of the first node. This
algorithm inserts ITEM into the list as the first node.

Step 1 : [Create a new node and store its address in the pointer NewNode]
NewNode = Address of new node
Step 2 : [Copy the information for the new node to the information part]
INFO[NewNode] = element
Step 3 : [Set the contents of the link part to contain the address of the first node]
LINK[NewNode] = HEAD
Step 4 : [Make the new node as the first node of the linked list]
HEAD = NewNode
Step 5 : Exit

The schematic diagram of Step 2, Step 3 and Step 4 are shown below
HEAD

3 5 7 NULL

9
NewNode
HEAD

3 5 7 NULL

9
NewNode
Linked List
22
HEAD

9 3 5 7 NULL
NewNode

Figure 4.7 Insert an ITEM (9) at the beginning of the list.

Function to insert a node at the beginning of the linked list

void Insert_Beginning( int ITEM )


{
NODE *NewNode;

NewNode= (NODE *) malloc(sizeof(NODE));

NewNode->info=ITEM;
NewNode->link=HEAD;
HEAD = NewNode;

4.12.4.2 INSERT A NODE AT THE END OF THE LINKED LIST

In some of the applications we have to append an item at the end of the list. To
append an item to a linked list, we loop through the list until find the element whose
link member points to NULL. The following algorithm is used to insert a node into a
linked list as a last node.

ALGORITHM 4.4:

Let LIST be a list stored in memory, HEAD gives the address of the first node. This
algorithm inserts ITEM into the list as the last node. CurrPTR is a pointer, which is
pointing to the current node of the list.

Step 1 : [Create a new node and store its address in the pointer NewNode]
NewNode = Address of new node
Step 2 : [Copy the information for the new node to the information part]
INFO[NewNode] = element
Step 3 : [Set the contents of the link part to NULL]
LINK[NewNode] = NULL
Step 4 : [Initialize HEAD value to CURRPTR ]
CurrPtr = HEAD
Step 5 : [Find the last node of the list]
While LINK[CurrPtr] != NULL Do
Step 6 : [Move CURRPTR to next node]
CurrPtr = LINK[CurrPtr]
Linked List
23
[WhileEnd]
Step 7 : [Connect the new node to the link of the last node]
LINK[CurrPtr] = NewNode
Step 8: Exit

The schematic diagram of Step 6 and Step 7 are shown in Figure

CurrPtr
HEAD

NewNode
3 5 7 NULL 9 NULL

CurrPtr
HEAD

NewNode
3 5 7 NULL 9 NULL

HEAD

NewNode
3 5 7 9 NULL

Figure 4.8 Insert an ITEM (9) at the end of the list.

Function to insert a node at the end of the linked list

void Insert_End (int ITEM)


{
NODE *NewNode, *CurrPtr;

NewNode= (NODE *) malloc(sizeof(NODE));


NewNode->info=ITEM;
NewNode->link=NULL;

CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;

CurrPtr->link=NewNode;
}
Linked List
24
4.12.4.3 INSERT A NODE AT A GIVEN POSITION

Suppose we are given the ITEM, which has to be placed at a given position in the
linked list. The following is an algorithm, which inserts ITEM into LIST so that ITEM is
placed at the required position.

ALGORITHM 4.5:

Let LIST be a list stored in memory, HEAD gives the address of the first node. This
algorithm inserts ITEM into the list at the position POS. CurrPTR is a pointer, which is
pointing to the current node of the list.

Step 1 : [Create a new node and store its address in the pointer NewNode]
NewNode = Address of new node
Step 2 : [Copy the information for the new node to the information part]
INFO[NewNode] = element
Step 3 : [Initialize HEAD value to CURRPTR ]
CurrPtr = HEAD
Step 4 : [Move to the required position]
For I = 1 to POS - 1 and CurrPtr != NULL Do
Step 5 : [Move CURRPTR to next node]
CurrPtr = LINK[CurrPtr]
[ForEnd]
Step 6 : [Check whether the position is found or not]
If ( CurrPtr = NULL)
Print “ Position Out Of Range”
Exit
Step 7 : Else
[Insert the new node at the required position]
LINK[NewNode] = LINK[CurrPtr]
LINK[CurrPtr] = NewNode
[EndIf]
Step 8: Exit

The schematic diagram of Step 4 and Step 7 are shown in Figure

CurrPtr
HEAD

3 5 7 NULL

NewNode
Linked List
25
CurrPtr
HEAD

3 5 7 NULL

9
NewNode

HEAD

3 5 9 7 NULL

NewNode

Figure 4.9 Insert an ITEM (9) at the third position of the list.

Function to insert a node at a given position

void Insert_Position( int ITEM, int POS)


{
NODE *NewNode,*CurrPtr;
int i;

NewNode= (NODE *) malloc(sizeof(NODE));


NewNode->info=ITEM;

CurrPtr = HEAD;
for( i = 1; i< POS - 1 && CurrPtr != NULL; i++)
CurrPtr = CurrPtr->link;

if ( CurrPtr ==NULL)
{ printf(“Position Out Of Range\n”);
exit(0);
}
NewNode->link = CurrPtr->link;
CurrPtr->link = NewNode;
}

Program 4.10 : To create a linked list and insert an element into it

#include <stdio.h>
#include <stdlib.h>
Linked List
26
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;

void Create_link_list(int);
void Display(NODE *);
void Insert_Beginning(int);
void Insert_End(int);
void Insert_Position(int,int);

void main()
{
int ele,pos;
char ch;

clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);

printf(“\nInsert Operation\n\n”);
do
{
printf(“\nChoose Position To Insert: \n”);
printf(“\n1. AT THE BEGINING”);
printf(“\n2. AT THE END”);
printf(“\n3. AT A GIVEN POSITION”);
printf(“\n4. EXIT”);
printf(“\n\nEnter your choice : “);
scanf(“%d”,&ch);

switch(ch)
{
case 1: {
Linked List
27
printf(“\nEnter element to add : “);
scanf(“%d”,&ele);
Insert_Beginning(ele);
printf(“\nThe linked list is \n”);
Display(HEAD);
break;
}
case 2: {
printf(“\nEnter element to add : “);
scanf(“%d”,&ele);
Insert_End(ele);
printf(“\nThe linked list is \n”);
Display(HEAD);
break;
}
case 3: {
printf(“\nEnter element to add : “);
scanf(“%d”,&ele);
printf(“\nEnter position to add: “);
scanf(“%d”,&pos);
Insert_Position(ele,pos);
printf(“\nThe linked list is \n”);
Display(HEAD);
break;
}
}
}while(ch != 4);
getch();
}

/* Function to add a node to the linked list */


void Create_link_list(int ele)
{
NODE *NewNode,*CurrPtr;

NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
NewNode->link=NULL;

if( HEAD==NULL)
HEAD=NewNode;
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr->link=NewNode;
}

}
Linked List
28
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}

/* Function to insert a node at the beginning of the linked list */


void Insert_Beginning( int ITEM )
{
NODE *NewNode;

NewNode= (NODE *) malloc(sizeof(NODE));

NewNode->info=ITEM;
NewNode->link=HEAD;
HEAD = NewNode;
}

/* Function to insert a node at the end of the linked list */


void Insert_End (int ITEM)
{
NODE *NewNode, *CurrPtr;

NewNode= (NODE *) malloc(sizeof(NODE));


NewNode->info=ITEM;
NewNode->link=NULL;
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;

CurrPtr->link=NewNode;
}

/* Function to insert a node at a given position in a linked list */


void Insert_Position( int ITEM, int POS)
{
NODE *NewNode,*CurrPtr;
int i;

NewNode= (NODE *) malloc(sizeof(NODE));


NewNode->info=ITEM;

CurrPtr = HEAD;
Linked List
29
for( i = 1; i< POS-1 && CurrPtr != NULL; i++)
CurrPtr = CurrPtr->link;
if ( CurrPtr ==NULL)
{ printf(“Position Out Of Range\n”);
exit(0);
}

NewNode->link = CurrPtr->link;
CurrPtr->link = NewNode;
}

OUTPUT
Linked list creation
Enter information field of the node 56
Do you wish to enter one more node ? y
Enter information field of the node 89
Do you wish to enter one more node ? y
Enter information field of the node 23
Do you wish to enter one more node ?n
Linked list elements
56 89 23 NULL
Insert Operation
Choose Position To Insert:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 1
Enter element to add : 15
The linked list is
15 56 89 23 NULL
Choose Position To Insert:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 2
Enter element to add : 19
The linked list is
15 56 89 23 19 NULL
Choose Position To Insert:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 3
Enter element to add : 65
Enter position to add: 2
The linked list is
15 65 56 89 23 NULL
Linked List
30
4.13 GARBAGE COLLECTION

Computers do not have an infinite amount of storage and cannot manufacture


more storage for immediate utilization. Therefore there are a finite number of nodes
available and it is impossible to use more than that number at any given instant. If it is
desired to use more than the number over a given period of time, some nodes must be
reused. Suppose memory space becomes reusable because a node is deleted from a list
or an entire list is deleted from a program. Clearly, we require the space to be available
for future use. One way to bring this about is to immediately reinsert the space into
free-storage list. But this is time consuming. So the operating system of a computer
periodically collects all the deleted space onto the free-storage lists. Any technique,
which does this collection, is called garbage collection.

Garbage collection usually takes place in two steps. First the computer run
through all lists, tagging those cells which are currently in use, and then the computer
runs through the memory, collecting all untagged space onto the free-storage list. The
garbage collection may take place when there is only some minimum amount of space
or no space at all left in free-storage list or when CPU is idle and has time to do the
collection. Generally speaking, the garbage collection is invisible to the programmer.
The free( ) function in C returns a node to the free pool, i.e availability list. This function
makes a node that is no longer being used in the linked list available for reuse. The
following function FreeNode( ) is used to remove a node temp from the linked list and
inserted into availability list.

Function to delete a node and insert this node into availablity list

void FreeNode( )
{
NODE *temp;
free(temp);
}

4.14 DELETING AN ITEM FROM THE LINKED LIST

To delete an existing node from a linked list, we have to loop through the nodes
until we find the node we want to delete. We should follow the steps below to delete a
node from a linked list:

1. If the linked list is empty, then deletion is not possible and this condition is
called as underflow condition.
2. To delete a particular node, we have to loop through the nodes until we find
the node we want to delete.
3. If the end of the list has been reached, “Position out of range” message can
be displayed.
4. Insert deleted node into the free area.

The deletion operation is classified into following types:


1. Deletion of the first node.
2. Deletion of the last node.
3. Deleting of the node at a given position.
Linked List
31
4.14.1 DELETION OF FIRST NODE

To delete the first node, we just change the HEAD pointer to point to the second
node or to contain NULL if we are deleting the only node in a one-node list. Suppose we
have a linked list as shown in Figure and want to delete first node.

HEAD

3 5 7 9 NULL

HEAD

5 7 9 NULL

Figure 4.10 Delete first node form the linked list

We don’t show a complete code walk-through because the code is so


straightforward. Instead, we show the state of the data structures in two stages: after
the first two statements and at the end. We use one of our previous lists. Following is
the data structure after the execution of the first two statements in the program segment.
The following algorithm deletes the first node from the linked list and insert-deleted
node into availability list.

ALGORITHM 4.6:

Let LIST be a linked list stored in memory. It deletes first node from the linked list.
HEAD gives the address of the first node.

Step 1 : [ List empty ?]


If HEAD = NULL
Display “Under flow”
Exit
[EndIf]
Step 2 : [ Initialize pointer variable CurrPtr]
CurrPtr = HEAD
Step 3 : [Delete first node]
HEAD = LINK[CurrPtr]
Step 4 : [Return deleted node to the AVAIL list]
FREE[CurrPtr]
Step 5 : Exit

Function to delete a node at the beginning of the linked list


Linked List
32

int Delete_Beginning( )
{
NODE *CurrPtr;
int ele;

if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
ele = CurrPtr->info;
HEAD = CurrPtr->link;

free(CurrPtr);
return(ele);
}

4.14.2 DELETION OF LAST NODE

To delete a last node of a linked list, we have to scan the list from the beginning
and find the address of the next to last node and assign NULL to link field of the next to
last node. The following algorithm deletes the last node from the linked list and insert-
deleted node into availability list. Following is the data structure after the execution of
the function.
CurrPtr
HEAD

3 5 7 NULL 9 NULL

PrevPtr

HEAD

3 5 7 NULL

Figure 4.11 Delete last node from the linked list

ALGORITHM 4.7:

Let LIST be a linked list stored in memory, It deletes first node from the linked list.
HEAD gives the address of the first node. CurrPtr is a pointer, which is being pointing
Linked List
33
current node of the list. PrevPtr is a pointer, which is pointing the previous node of the
current node.
Step 1 : [List empty ?]
If HEAD = NULL Then
Display “Under flow”
Exit
[EndIf]
Step 2 : [ Initialize pointer variables CurrPtr ]
CurrPtr = HEAD
Step 3 : [Traverse linked list and take the pointer to next node]
While (LINK(CurrPtr) != NULL) Do
Step 4 : PrevPtr = CurrPtr
Step 5 : CurrPtr = LINK[CurrPtr]
[ End of While ]
Step 6 : LINK[PrevPtr] = NULL
Step 7 : [Return deleted node to the AVAIL list]
FREE[CurrPtr]
Step 8: Exit

Function to delete the last node of the linked list

int Delete_End( )
{
NODE *CurrPtr,*PrevPtr;
int ele;

if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
while ( CurrPtr->link != NULL)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}

ele = CurrPtr->info;
PrevPtr->link = NULL;

free(CurrPtr);
return(ele);
}

4.14.3 DELETING THE NODE AT A GIVEN POSITION

The function for deleting a node at a given position involves the following steps.
Linked List
34
1. Find the location of the node with CurrPtr, and location of previous node
with PrevPtr.
2. Delete the node (This is nothing but deleting the node following a given node).

CurrPtr
HEAD

3 5 7 9 NULL

PrevPtr

HEAD

3 5 9 NULL

Figure 4.12 Delete the node at the third position of the list.

ALGORITHM 4.8:

Let LIST be a linked list stored in memory, It deletes first node from the linked list.
HEAD gives the address of the first node. POS is the position of the node, which is to be
deleted. CurrPtr is a pointer, which is being pointing to the node at a given position of
the list. PrevPtr is a pointer, which is pointing the previous node of the current node.

Step 1 : [List empty ?]


If HEAD = NULL Then
Display “Under flow”
Exit
[EndIf]
Step 2 : [ Initialize pointer variables CurrPtr]
CurrPtr = HEAD
Step 3 : [Traverse linked list and take the pointer to the desired position]
For I = 1 to POS and CurrPtr != NULL Do
Step 4 : PrevPtr = CurrPtr
Step 5 : CurrPtr = LINK[CurrPtr]
[ End of For ]
Step 6 : If CurrPtr = NULL Then
Display “Position out of range”
Exit
[EndIf]
Step 7 : [Delete the node]
Linked List
35
LINK(PrevPtr) = LINK(CurrPtr)
Step 8: [Return deleted node to the AVAIL list]
FREE(CurrPtr]
Step 9: Exit

Function to delete a node at a given position of the linked list

int Delete_Position( int POS )


{
NODE *CurrPtr,*PrevPtr;
int ele,i;

if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
for( i = 1; i< POS && CurrPtr != NULL; i++)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}
if ( CurrPtr == NULL)
{
printf(“\nPositon out of range”);
exit(0);
}
ele = CurrPtr->info;
PrevPtr->link = CurrPtr->link;

free(CurrPtr);
return(ele);
}

Program 4.11: To create a linked list and delete an element from it

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;
Linked List
36
void Create_link_list(int);
void Display(NODE *);
int Delete_Beginning();
int Delete_End();
int Delete_Position(int);

void main( )
{
int ele,pos;
char ch;

clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);
printf(“\nDeletion Operation\n\n”);
do
{
printf(“\nChoose Position To Delete: \n”);
printf(“\n1. AT THE BEGINING”);
printf(“\n2. AT THE END”);
printf(“\n3. AT A GIVEN POSITION”);
printf(“\n4. EXIT”);
printf(“\n\nEnter your choice : “);
scanf(“%d”,&ch);

switch(ch)
{
case 1: {
ele = Delete_Beginning();
printf(“\nDeleted element is :%d “,ele);
printf(“\nThe linked list is \n “);
Display(HEAD);
break;
}

case 2: {
ele = Delete_End();
printf(“\nDeleted element is :%d “,ele);
printf(“\nThe linked list is \n “);
Linked List
37
Display(HEAD);
break;
}
case 3: {
printf(“\nEnter position to delete: “);
scanf(“%d”,&pos);
ele = Delete_Position(pos);
printf(“\nDeleted element is :%d “,ele);
printf(“\nThe linked list is \n “);
Display(HEAD);
break;
}
}
}while(ch != 4);
getch();
}

/* Function to add a node to the linked list */


void Create_link_list(int ele)
{
NODE *NewNode,*CurrPtr;

NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
NewNode->link=NULL;

if( HEAD==NULL)
HEAD=NewNode;
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;

CurrPtr->link=NewNode;
}

}
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}
Linked List
38
/* Function to delete a node at the beginning of the linked list */
int Delete_Beginning( )
{
NODE *CurrPtr;
int ele;

if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
ele = CurrPtr->info;
HEAD = CurrPtr->link;

free(CurrPtr);
return(ele);
}

/* Function to delete a node at the end of the linked list */

int Delete_End( )
{
NODE *CurrPtr,*PrevPtr;
int ele;

if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
while ( CurrPtr->link != NULL)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}

ele = CurrPtr->info;
PrevPtr->link = NULL;

free(CurrPtr);
return(ele);
}

/* Function to delete a node at a given position of the linked list */


int Delete_Position( int POS )
{
NODE *CurrPtr,*PrevPtr;
Linked List
39
int ele,i;

if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
for( i = 1; i< POS && CurrPtr != NULL; i++)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}
if ( CurrPtr == NULL)
{
printf(“\nPositon out of range”);
exit(0);
}
ele = CurrPtr->info;
PrevPtr->link = CurrPtr->link;

free(CurrPtr);
return(ele);
}

OUTPUT
Linked list creation
Enter information field of the node 56
Do you wish to enter one more node ? y
Enter information field of the node 89
Do you wish to enter one more node ? y
Enter information field of the node 23
Do you wish to enter one more node ? y
Enter information field of the node 35
Do you wish to enter one more node ?n
Linked list elements
56 89 23 35 NULL
Deletion Operation
Choose Position To Delete:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 1
Deleted element is : 56
The linked list is
89 23 35 NULL
Choose Position To Delete:
Linked List
40
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 2
Deleted element is : 35
The linked list is
89 23 NULL
Choose Position To Delete:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 3
Enter position to delete: 2
Deleted element is : 23
The linked list is
89 NULL

4.15 CIRCULAR LINKED LINEAR LIST

Some applications do not require that there be a particular first or last list element.
In such cases, it may be convenient to allow access from the last element to the first. In
the normal linked list, the link field of the last element stores the value NULL. By instead
storing a pointer to the first element in the list, a circular list is created. With this
implementation, a TAIL pointer is no longer needed. Figure illustrates a circular singly
linked list. The primary danger with such implementations is that list-processing
operations may go into infinite loop since there is no obvious end to the list. However,
the HEAD pointer can be used as a marker to determine when list processing has
worked full circle through the list.

HEAD

3 5 9 7

Figure 4.13 Circular Linked List

ALGORITHM 4.9:

HEAD is a header node which contains three fields, NodeNo, INFO and LINK. The LINK
field holds the address of the first node in a circular linked list. CurrPtr is a pointer
which is being pointing current node of the list.

Step 1 : [ Create a head node]


HEAD=Create a node
Step 2 : [ Create a new node ]
Linked List
41
LINK[HEAD] = new node
Step 3 : [ Initialize node number ]
count = 0
Step 4 : [CurrPtr is always point to the last node in the linked list]
CurrPtr = LINK[HEAD]
Step 5 : Read INFO[CurrPtr]
Step 6 : [ Increment node number ]
count = count+1
Step 7 : NodeNo[CurrPtr] = count
Step 8 : [Create a New Node ?]
If answer is yes Then
(a) [Allocate space to newly created node ]
NewNode = Create a node
(b) [ NewNode address is assigned to LINK field of the previous Node]
LINK[CurrPtr]=NewNode
(c) [CurrPtr pointer should point next node in the list, i.e., NewNode]
CurrPtr=LINK[CurrPtr]
(d) GOTO Step 8
Else
(a) [Last node of the linked list. last node link field should point head
node of the circular list]
LINK[CurrPtr]= HEAD
Step 9 : Return

Program 4.12:To illustrate circular linked list operations (Creation and traversing).

#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <stdlib.h>
struct node
{
int NodeNo;
int info;
struct node *link;
};
typedef struct node NODE;
int count=0;
/* Function to create a circular linked list */
void Create_Circular_list(NODE *head)
{
char ans;
NODE *CurrPtr;
head->link=(NODE *)malloc(sizeof(NODE));
CurrPtr=head->link;
while(1)
{
Linked List
42
count++;
printf(“Enter information field of the node “);
scanf(“%d”,&CurrPtr->info);
CurrPtr->NodeNo=count;
printf(“\nDo you want enter next node ? “);
scanf(“ %c”,&ans);
if(toupper(ans)==’N’)
{
CurrPtr->link=head;
break;
}
CurrPtr->link=(NODE *)malloc(sizeof(NODE));
CurrPtr=CurrPtr->link;
}
head->NodeNo=count;
}
/* Function to display circular linked list elements */
void Display(NODE *head)
{
int i;
head=head->link;
for(i=1;i<=count;head=head->link,i++)
printf(“\nNode %d information is %d”,head->NodeNo,head->info);
}
/* Main function */
void main( )
{
NODE *head;
clrscr();
head=(NODE *)malloc(sizeof(NODE));
Create_Circular_list(head);
printf(“Number of nodes in the circular linked list is %d”,head->NodeNo);
Display(head);
}

OUTPUT
Enter information field of the node 25
Do you want enter next node ? y
Enter information field of the node 40
Do you want enter next node ? y
Enter information field of the node 60
Do you want enter next node ? y
Enter information field of the node 5
Do you want enter next node ? n
Number of nodes in the circular linked list is 4
Node 1 information is 25
Node 2 information is 40
Node 3 information is 60
Node 4 information is 5
Linked List
43
4.15.1 ADVANTAGES OF CIRCULAR LINKED LIST

1. In a circular linked list every node is accessible from a given node. That is
from the given node, nodes can be reached by merely chaining the list.
2. Concatenation and splitting the operations are more efficient.

4.15.2 DISADVANTAGES OF CIRCULAR LINKED LIST

1. In processing, it is possible to get into an infinite loop.

4.16 DOUBLY LINKED LIST

The singly linked list presented in previous section allows for direct access from
a list node only to the next node in the list. This list is named as singly linked list
because each list element contains a pointer to the next element. In singly linked list,
traversing is possible only in one direction. Sometimes it is required to traverse a list in
forward direction or backward direction. A doubly linked list is designed to allow
convenient access from a list node to the next node and also to the preceding node on
the list. This is also used to traverse the list in both the directions.

In a doubly linked list each node has not only pointer to the next node but also
a pointer to the prior node. Each node of doubly linked list is divided into three parts
(fields):

1. A pointer BACK (leftlink) which contains the location of the preceding node
in the list.
2. An information field INFO which contains data of N.
3. A pointer FORW (rightlink) which contains location of the next node in the
list.

HEAD

NULL 3 5 7 NULL

Figure 4.14 Doubly linked list

The doubly linked list is also called as two-way list because we can traverse the
list in two directions: in the usual forward direction from the beginning of the list to
end, or in the backward direction from the end of the list to the beginning.

The doubly linked list is useful primarily because it is easier to implement


operations than a singly linked list. We may consider the nodes on a doubly linked list
to consists of three fields: an info field that contains the information stored in the node,
and left and right fields that contain pointers to the nodes on either side. In the figure,
LEFT and RIGHT are pointer variables denoting the left-most and right-most nodes in
the list, respectively. The left link of the left-most node and the right link of the right-
Linked List
44
most node are both NULL, indicating the end of the list for each direction. The left and
right links of a node are denoted by the variables llink and rlink, respectively. We may
declare a set of such nodes using dynamic implementation, by

struct node
{
int info; // Information field
struct node *rlink; // a pointer which is pointing right node
struct node *llink; // a pointer which is pointing left node
};

ALGORITHM 4.10:

This algorithm is used to create a doubly linked list whose left-most and right-most
node addresses are given by the pointer variables LEFT and RIGHT, respectively.

Step 1 : [ Initialize LEFT and RIGHT pointers ]


LEFT = NULL and RIGHT = NULL
Step 2 : [ Create a doubly linked list ]
Repeat Step 3 through Step 6 to create required number of nodes for
linked list.
Step 3 : [ Obtain new node from availability list ]
NewNode = Address of a new node
Step 4 : [ Copy information field ]
INFO[NewNode] = ITEM
Step 5 : RLINK[NewNode] = NULL and LLINK[NewNode]=NULL
Step 6 : [ Insertion into an empty list ?]
If RIGHT = NULL Then
(a) RIGHT =NewNode and LEFT = NewNode
Else
(a) LLINK[NewNode] =RIGHT
(b) RLINK[RIGHT] =NewNode
(c) RIGHT = RLINK[RIGHT]
[ EndIf ]
[End of Step 2 Loop ]
Step 7 : End

Program 4.13 : Program to create a doubly linked list.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *rlink;
struct node *llink;
};
Linked List
45
typedef struct node NODE;
/* Function to display doubly linked list in forward direction */
void Display_Forward(NODE *CurrPtr)
{
while(CurrPtr)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->rlink;
}
}
/* Function to display doubly linked list in backward direction */
void Display_Backward(NODE *CurrPtr)
{
while(CurrPtr)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->llink;
}
}
/* Function to create a doubly linked list node */
NODE *GetNode()
{
NODE *NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->llink=NULL;
NewNode->rlink=NULL;
printf(“Enter information field of the node “);
scanf(“%d”,&NewNode->info);
return NewNode;
}
/* Main function */
void main( )
{
NODE *RIGHT=NULL,*LEFT=NULL,*NewNode;
char ans;
clrscr( );
while(1)
{
printf(“Do you want to enter a new node ?”);
scanf(“ %c”,&ans);
if(toupper(ans)==’N’)break;
NewNode=GetNode();
if(RIGHT==NULL)
{
LEFT=NewNode;
RIGHT=NewNode;
}
else
{
NewNode->llink=RIGHT;
Linked List
46
RIGHT->rlink=NewNode;
RIGHT=RIGHT->rlink;
}
}
printf(“\nDoubly Linked list elements \n”);
Display_Forward(LEFT);
printf(“\nDoubly linked list in the reverse direction \n”);
Display_Backward(RIGHT);
}

OUTPUT
Do you want to enter a new node ? y
Enter information field of the node 34
Do you want to enter a new node ? y
Enter information field of the node 56
Do you want to enter a new node ? y
Enter information field of the node 7
Doubly Linked list elements
34 56 7
Doubly linked list in the reverse direction
7 56 34

4.16.1 ADVANTAGES OF DOUBLY LINKED LIST

1. One can traverse the list in both directions.


2. Insertions and deletions are easy.
3. It is used to represent trees.

4.16.2 DISADVANTAGE OF DOUBLY LINKED LIST

1. Extra memory is required to store RIGHT and LEFT pointers.

4.17 MERITS OF AN ARRAY OVER LINKED LIST

1. It is easy to compute the address of an element in an array.


2. Linear relationship is reflected by the physical relationship of the data in
memory.
3. Extra memory space is not required to store link fields.
4. Binary search is applicable
5. Sorting an array is easier.
6. Once can directly access any element of the array.

4.18 DEMERITS OVER LINKED LIST

1. Additions and deletions are not easy.


2. It cannot be used in application where there is an unpredictable storage
requirement.

You might also like