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

Module 2_2022 Scheme

This document covers the concepts of queues and linked lists, detailing their structures, operations, and implementations. It explains the differences between linear and circular queues, including their advantages and disadvantages, as well as how to manage overflow and underflow conditions. Additionally, it discusses dynamic arrays for circular queues to address limitations of static allocation.

Uploaded by

freefireb2k444
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Module 2_2022 Scheme

This document covers the concepts of queues and linked lists, detailing their structures, operations, and implementations. It explains the differences between linear and circular queues, including their advantages and disadvantages, as well as how to manage overflow and underflow conditions. Additionally, it discusses dynamic arrays for circular queues to address limitations of static allocation.

Uploaded by

freefireb2k444
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 95

MODULE 2

QUEUES AND
LINKED LISTS
CONTENTS
 QUEUES
 Queues
 Circular Queues
 Using Dynamic Arrays
 Multiple Stacks and queues.
 LINKED LISTS
 Singly Linked Lists
 Lists and Chains
 Representing Chains in C
 Linked Stacks and Queues

Polynomials
QUEUES
 Like a Stack, a Queue is also an ordered list of items.

 However, a queue is different from a stack with respect to


the insertion and deletion operations.

 In a queue, addition of elements takes place from one end.


This end is called REAR end of the queue.

 The deletion of elements takes place from another end and


this end is called FRONT end of the queue.

“A Queue is a linear list of elements in which deletions


can take place only at one end called the FRONT and
insertions can take place only at the other end called REAR.”
QUEUES
 Queue follows FIFO(First In First Out) logic.

 An element that is inserted first will be the first element


to get deleted.

 Addition and Deletion of elements in a queue


0 1 2 3 4 r
Q[ Insert
5] r=
f= -1, 0 1 2 3 4
Cf= -
-1 1 A B C
r
Insert
0 1 2 3 4 r
Af= - Insert
1 A 0 1 2 3 4
Df= -
1 A B C D
r
Insert
0 1 2 3 4
Bf= -
1 A B
QUEUES
f r
Delet
e
0 1 2 3 4 Deleted
B C D element is A

f r
Delet
e
0 1 2 3 4 Deleted
C D element is B

f r
Delet
0 1 2 3 4 Deleted
e
D element is C

f, r
Delet
e
0 1 2 3 4 Deleted
element is D
QUEUES
ADT Queue is
objects: a finite ordered list with zero or more elements
functions: for all queue Є Queue, item Є element, maxQueueSize Є
positive integer
Queue CreateQ(maxQueueSize) ::= create an empty queue whose maximum
sixe is maxQueueSize.
Boolean IsFullQ(queue, maxQueueSize) ::= if(number of elements in queue
== maxQueueSize)
return TRUE else return FALSE. Queue
AddQ(queue, item) ::= if(IsFullQ(queue)) queue full
else insert item at the rear of queue and return queue
Boolean IsEmptyQ(queue) ::=
if(queue == CreateQ(maxQueueSize)) return TRUE
else return FALSE.
Element DeleteQ(queue) ::= if(IsEmptyQ(queue) ) return
else remove and return the item at front of the queue.
QUEUES
Array representation of Queue
 Queues are represented using a linear array with two indices
namely Front and Rear.

 The linear array will be named Queue.

 The Front index points to the front/first element of the


Queue. The Rear index points to the rear/last element of
the Queue.

 A Queue represented using a linear array is presented below,


1 2 3 4 5 …… N
Front =
0
Rear = Queue[
0 N]
QUEUES
Queue Operations
 The most common operations performed on a queue are:
 Insertion(includes check for overflow)

 Deletion(includes check for underflow)

 Display

 The above operations are presented in the following


sequence of figures.
1 2 3 4
Front =
0
Rear = 1 2 3 4
0 =
Front AAA
0
Rear =
1
QUEUES
1 2 3 4
Front = AAA BBB
0
Rear = 1 2 3 4
Front
2 = AAA BBB CCC
0
Rear = 1 2 3 4
Front
3 = AAA BBB CCC DDD When Rear = N, Queue
0 is FULL
Rear =
Now we4 can display the elements of the Queue by
visiting each element from (Front + 1) to Rear.
1 2 3 4
Front = BBB CCC DDD Deleted element
1 is AAA
Rear = 1 2 3 4
Front
4 = CCC DDD Deleted element
2 is BBB
Rear =
QUEUES
1 2 3 4
Front = DDD Deleted element
3 is CCC
Rear = 1 2 3 4
Front
4 = Deleted element
4 is DDD
Rear =
We can
4 conclude that when Front = Rear the Queue is
empty.
Queue
Insertion void insertQ(int item){
if(Rear == N)

Printf(“Overflow”);
else{
Rear = Rear + 1;
Queue[Rear] =
QUEUES
Queue
Deletion int deleteQ (){
if(Front == Rear)

Printf(“Underflow”);
else{
Front= Front +
1;
return
Queue Queue[Front];
Display void displayQ
} (){
int i;
for(i = Front+1;
i<=Rear; i++)
printf(“%d”,
QUEUES
Disadvantage of a Linear Queue
 Consider the following queue
1 2 3 4
Front =
0
 Rear =
We now perform some insertions and deletions on this queue.
0
1 2 3 4
Front = AAA BBB CCC DDD
2
0
1
Rear =
 Now the question
1 is, Can we insert another element in the
4
2
3
queue?

 The answer is NO. This is because we have reached the overflow


condition.

 This is the disadvantage of a Linear Queue.


QUEUES
 There are two ways to overcome this disadvantage:
 Left shift the queue elements after every deletion
 Use Circular Queues

Left Shift after deletions


 In this approach, after an element in the queue is deleted,
we shift the remaining elements to their left by one position.

 This ensures that after every deletion, there is space created


in the queue for another element to be inserted.

 Consider the queue,


1 2 3 4 5
Front = AAA BBB CCC DDD EEE
0
Rear =
QUEUES
 We now delete the first element in the queue, which results in,
1 2 3 4 5
Front = BBB CCC DDD EEE
1
Rear =
 Next we left5shift the remaining elements of the queue.
1 2 3 4 5
Front = BBB CCC DDD EEE
1
Rear =
 We also adjust
5 the Front and Rear indices accordingly.
1 2 3 4 5
Front = BBB CCC DDD EEE
0
Rear =
 Hence by using the left shift approach, we are able to overcome the
4
disadvantage of the linear queue. However, shifting of elements in a
queue, especially a large queue is very time consuming.
CIRCULAR QUEUE
 A Circular Queue is a queue where the end of the queue
is followed by the beginning of the queue.

 Let MAX be the size of a circular queue. This means that


the queue will have indices from 1 to MAX.

 In this queue, the index MAX will be followed by index 1.

2
 A circular queue is presented below.
3

1 2 3 …. MA
X 1

Linear Queue …

MA Circular
CIRCULAR QUEUE
 This circular representation helps us to easily overcome
the problem that we encountered in a linear queue.

 We now insert a few elements in the circular queue.


2 2
3 2 3
0 3
r++; 0
1 1 1
10
40
Q[r] = 50
20
30
0 4
4 0 4
50
5 5
f = 0, r f = 0, r
=0 =51
2
3
4
Q[5]
CIRCULAR QUEUE
 After inserting 5 elements in the queue, it becomes full.
Any attempt to insert another element in the queue
results in an overflow.

 Let us now delete an element from the circular queue.


2 2
2 3 2 3
0 3 f++; 0 3
1 1 0 Delete 1 0
0 Q[f];
4 4
0 4 0 4
50 50
5 5
f = 0, r f = 1, r
=5 =5
CIRCULAR QUEUE
 This deletion has resulted in one free space getting
created in the circular queue.

 In case of a linear queue, this deletion would not have


made any difference as r = MAX and hence queue is full.

 However, since we have a circular queue, the created


empty space can be made use of.

 We can insert another element into the queue as index 5


is followed by index 1.

 Now the task is to bring the rear index from its current
position 5 to index 1.
CIRCULAR QUEUE
 We simply cannot increment the value
of r as this will result in r=6, which is
2
not a valid index position in the circular
queue.
2 3
0 3
1 0  In circular queue, we use the %
operator to perform the increment.
4
0 4
50
 The increment operation is performed
5
as,
f = 1, r r = (r+1) % MAX
=5

 In our example
r = (r+1) % MAX
r = (5+1) % 5 = 6 % 5= 1
CIRCULAR QUEUE
 Similarly the front index is also incremented as,
f = (f +1)% MAX;

 With this, we will now be able to comfortably move the


indices Rear and Front in a circular fashion in the
circular queue.

 With the insertion and deletion operations for a circular


queue in place, we now see how to check for the
overflow and underflow conditions.

 For a linear queue,


Rear = MAX  Overflow condition
Front = Rear  Underflow condition
CIRCULAR QUEUE
 Consider the below circular queue.
2
2 3
0 3
f = 0, r 1 1 0
=50 0 4
0
5 4
0
5

 The above queue is empty when f = r. Hence we can consider this to


be the condition to check for underflow in the circular queue.

 Let us now insert 5 elements into the above queue.

 The queue is now full. The position of rear index is, r = MAX. Hence
this can be considered as the condition to check for overflow.
CIRCULAR QUEUE
2
2 3
0 3
f = 1,
0, r 1 1 0
6
=15 0
0 4
0
5 4
0
5
 Let us now delete an item from the above queue.
 With one free space available, we can insert another element
in the circular queue. On doing so, we get the above queue.
 We see that the queue is full again. However, what we
need to observe is the values of f and r.
 f = r and the queue is full. Earlier, we used the same condition
to check if queue is empty. This is a contradiction.
CIRCULAR QUEUE
 Hence, we can conclude that, in circular queues, the
overflow and underflow conditions cannot be
determined based on the positions of indices f and r.

 Instead, we use a variable count to keep track of the


number of elements in the circular queue.

 When an element in inserted into the queue, the count


value is incremented and when an element is removed
from the queue, the count value is decremented.

 Based on the value of count, we determine the


overflow and underflow conditions in a circular queue.
CIRCULAR QUEUE

Insertion operation in Deletion operation in


Circular Queue Circular Queue
void insertCQ(int item){ int deleteCQ( ){
if(count = = MAX) if(count = = 0)

printf(“Overflow”); printf(“Underflow”);
else{ else{
r = (r+1) % f = (f+1) %
MAX ; MAX ;
Q[r] = item; return Q[f];
count++; count- -;
} }
} }
CIRCULAR QUEUES USING DYNAMIC ARRAYS
 We go for dynamic allocation of circular queues to
overcome the drawbacks that exist in static allocation.

 Let capacity be the variable that represents the circular


queue size.

 Consider the following queue where we have performed


some insertions and deletions.
2
3
2
D
2 3
E
1 1 2 3 4 5 6 7 8
1
1
C 4F 4
4,
5,
f = 0,
3,
1, r
6,
2, C D E F G A B
=37
65
8
1
4
2
0 B
8 5
G r f
A 6 5
7 6
CIRCULAR QUEUES USING DYNAMIC ARRAYS
 Now consider we need to add 8 more elements into the
queue.

 With the current memory availability, this is impossible.

 Hence, the only option available is to resize the queue to


accommodate 8 more elements.

 Like we did in stacks, we double the size of the queue.

 Increasing the size of the queue alone is not going to help.

 It is also necessary to reorganize the indices f and r


accordingly.
CIRCULAR QUEUES USING DYNAMIC ARRAYS
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
C D E F G A B
r f
 Although we have increased the size of this queue, we
see that the queue is not at all in proper order.

 We reorganize the above queue by considering 2


segments in the queue.

 The first segment is made of elements {C,D, E, F,


G} and the second segment is made up of {A, B}.

 To bring the above queue to order, we perform some


CIRCULAR QUEUES USING DYNAMIC ARRAYS
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
C D E F G A B
r f

Segment Segment
1 2
Step 1
Create a new array newQueue whose size is twice the capacity.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Step 2
Copy the second segment (from queue[f+1] to queue[capacity –
1]) in the newQueue beginning at 0.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
A B
CIRCULAR QUEUES USING DYNAMIC ARRAYS
Step 3
Copy the first segment(from queue[0] to queue[rear]) in
newQueue beginning at capacity – f – 1.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
A B C D E F G

Step 4
Reorganize indices f and r.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
A B C D E F G
r f
 Now it is possible to comfortably add 8 more elements into the above
queue.

 Next we have a look at the function representing the above operations.


CIRCULAR QUEUES USING DYNAMIC ARRAYS
Consider the following queue

queu 0 1 2 3 4 5 6 7 capacity
e
00 0 0 0 0 0 0 0 0 =8
0 1 2 3 4 5 6 7 rear = 4
C D E F G A B front = 5
r f

First we create a new queue whose capacity is twice that


of above queue.
0 1 2 3 4 5 6 7 8 9 1 …….. 1
newQue
0 5
ue
70 7 7 7 7 7 7 7 7 7 7 8 ………. 8
0 1 2 3 4 5 6 7 8 9 0 5

 We next start copying segments from queue to newQueue.

 For this, we use a special function copy(a, b, c).


CIRCULAR QUEUES USING DYNAMIC ARRAYS
 This function copies elements from one queue,
starting from location a to location b – 1, and places
them in another queue starting at location c.
queu 0 1 2 3 4 5 6 7
e
00 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
C D E F G A B
r f
 To begin the copy process, we declare a variable start and
compute its value.

 After start has been computed, we begin the copy process.

 We first copy the second segment into newQueue. This is


presented next.
CIRCULAR QUEUES USING DYNAMIC ARRAYS
queu 0 1 2 3 4 5 6 7
e
00 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
C D E F G
r f A B

0 1 2 3 4 5 6 7 8 9 1 …….. 1
newQue
0 5
ue
70 7 7 7 7 7 7 7 7 7 7 8 ………. 8
0 1 2 3 4 5 6 7 8 9 0 5
A B
 Next we copy the first segment and place the
elements in newQueue.
newQue 0 1 2 3 4 5 6 7 8 9 1 …….. 1
0 5
ue
70 7 7 7 7 7 7 7 7 7 7 8 ………. 8
0 1 2 3 4 5 6 7 8 9 0 5
A B C D E F G
CIRCULAR QUEUES USING DYNAMIC ARRAYS
 The next set of statement adjust the positions of f and
r in newQueue.

queu 0 1 2 3 4 5 6 7
e
70
00 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
C D E F G
r f A B

0 1 2 3 4 5 6 7 8 9 1 …….. 1
0 5
newQue
7 7 7 7 7 7 7 7 7 7 8 ………. 8
ue
70 0 1 2 3 4 5 6 7 8 9 0 5
r f
A B C D E F G
MULTIPLE STACKS AND QUEUES
 Here we attempt to represent more than one stack in a 1D array.

 Let us first define a 1D array as follow,


#define MAX_SIZE 20
int s[MAX_SIZE];

0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9

s[MAX_SIZ
E]
 Consider that the above array must accommodate n =
4 stacks.

 We now divide the above array into 4 equal segments,


each representing one stack.
MULTIPLE STACKS AND QUEUES
 The division of the array into 4 segments is done as,
MAX_SIZE / n = 20 / 4 = 5

 Hence, the size of each stack is 5. The array now looks like,

0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9

Stack 0 Stack 1 Stack 2 Stack 3

 The next task is to uniquely identify each of the above


stacks.

 For this, we use two variables. They are:


 top – stack index
 boundary – used to indicate the stack boundary
MULTIPLE STACKS AND QUEUES
 Since there are multiple stacks, we need to have multiple
top and boundary indices.

 For this, we create an array of top and boundary indices as,


top[n], boundary[n];

 We now need to give initial values for these indices. We start


with top[n].

0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9

top[0] = top[1] = top[2] = top[3] = top[4] =


-1 4 9 14 19
MULTIPLE STACKS AND QUEUES
 In general, the initial value of top index for various
stacks is determined as follows.
for( j = 0; j <= n; j++) {
top[ j ] = MAX_SIZE / n
* j – 1;
 }
Next, we initialize the values of boundary index for various stacks.

for( j = 0; j <= n; j++) {


boundary[ j ] =
top[ j ];
}
0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9

top[0] = -1 top[1] = 4 top[2] = 9 top[3] = 14 top[4] = 19


boundary[0] boundary[1] boundary[2] boundary[3] boundary[4]
MULTIPLE STACKS AND QUEUES
We next start defining all the basic stack operations on
multiple stacks.

Overflow condition
Let us push 5 elements in each of the four stacks. The
resulting array is,

0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9
A E I M Q B F J N R C G K O S D H L P T
Stack 0 Stack 1 Stack 2 Stack 3
0
-1
top[0] = 1
2
3
4 5
4
top[1] = 6
7
8
9 9
11
10
12
13
top[2] = 14 15
14
top[3] = 16
17
18
19
boundary[0] boundary[1] boundary[2] boundary[3]
= -1 =4 =9 = 14
Hence, when the top of ith stack is at the same position as
boundary of (i+1)th stack, then we say that stack i is full.
MULTIPLE STACKS AND QUEUES
 The code for overflow condition in multiple stacks is,
if(top[ i ] = = boundary[ i +
1 ]){
printf(“stack %d is
full”, i);
Underflow } condition
Underflow condition is comparatively easy to define.
Stack 0 Stack 1 Stack 2 Stack 3
0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9

top[0] = -1 top[1] = 4 top[2] = 9 top[3] = 14 top[4] = 19


boundary[0] boundary[1] boundary[2] boundary[3] boundary[4]
= -1 =4 =9 = 14 = 19
When the top and boundary indices of ith stack are at
the same position we say that stack i is empty.
MULTIPLE STACKS AND QUEUES
 The code for underflow condition in multiple stacks is,
if(top[ i ] = = boundary[ i ])
{
printf(“stack %d is
empty”, i);
Push operation
}
void push( int item, int i){
if(top[ i ] = = boundary[ i
+ 1 ]){
printf(“stack %d is
full”, i);
}else{
top[ i ] ++;
s[ top[i] ] = item;
}
MULTIPLE STACKS AND QUEUES
Pop operation
int pop(int i){
if(top[ i ] = = boundary[ i ]){
printf(“stack %d is
empty”, i);
}else{
return s[ top[i] ] ;
top[ i ] - -;
}
}
Stack 0 Stack 1 Stack 2 Stack 3
0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9
1 1 2 3
0 top[0]
5 = -1
0
1 top[1] = 4 5 top[2]
5 = 11
9
10 top[3] = 14
boundary[0] boundary[1] boundary[2] boundary[3]
= -1 =4 =9 = 14

push(10,
pop(2)
push(15,
push(25,
push(35, 35 is popped from
MULTIPLE STACKS AND QUEUES
Display operation
void display(int i){
if(top[ i ] = = boundary[ i ]){
printf(“stack %d is empty”, i);
}else{
for( j = boundary[i] + 1; j<= top[
i ]; j++){
printf(“%d”, s[j]);
}
}
Stack 0 Stack 1 Stack 2 Stack 3
0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9
1 1 2 3
0 top[0]
5 = -1
0
1 top[1] = 4 5 top[2]
5 = 11
9
10 top[3] = 14
boundary[0] boundary[1] boundary[2] boundary[3]
= -1 =4 =9 = 14

display(
LINKED LIST
 One way by which we can store a list of items is using arrays,
in which every item is stored in consecutive memory
locations.

 However, the disadvantage of arrays is operations like


insertion and deletion are expensive to perform.

 Also changing the size of an array is not a straightforward


task.

 An alternate way of storing a list of items in the memory is by


considering each item as an individual entity and storing it.

 Also every item will have a field called link, that contains the
address of the next item in the list.
LINKED LIST
 This means, we need not store successive items of the list in
successive memory locations.

 Such an arrangement also makes insertion and deletion of items


very easy. This is accomplished using a data structure called
Linked List.

“A Linked List or One-Way List is a linear collection of data


elements, called nodes, where the linear order is given by means
of pointers.”

 Hence, for a given list of items, if array is used to store the


items, then the sequence of items in the array must be same as
the sequence mentioned in the list.

 However, with linked list, the sequence need not be the same as
mentioned.
LINKED LIST
 Each node in a linked list is divided into two parts:
 info - contains the information about the element
 link – contains the address of the next node in the list

 A linked list of 6 nodes is diagrammatically presented below.

STAR
T info link

 The info part of a node can either contain a single data item or a
group of data items.

 The link part holds the address of the next node in the list.

 The linked list also has a list pointer, called START, that points to the
first node of the list. START indicates the beginning of the list.
REPRESENTATION OF LINKED LISTS IN MEMORY
 Since a simple linked list is made up of two parts(info and link),
a linked list is maintained using two linear arrays in the memory.

 One array is called the INFO array and it contains the


information of all linked list nodes.

 The second array is called the LINK array and it contains the
addresses of next nodes in the linked list.

 The index positions in the array correspond to the list nodes.

 For an index position k, INFO[k] and LINK[k] will contain the


data in node k and address of next node to k respectively.

 The list also requires a variable, called START, that points to the
first node of the list.
REPRESENTATION OF LINKED LISTS IN MEMORY
 Consider the following linked list.
STAR
T N O E X I T X

 The memory representation of the above list is,


1 E 10
2
3 N 8
STAR 4
T3 5 _ 1
6 T 0
7
8 O 5
9 I 6
1 X 9
0
1
1 INFO LINK
REPRESENTATION OF LINKED LISTS IN MEMORY
 Array representation of two lists
AL
G 8 7 9 82 X
8 4 3
GEO
M 8 6 7 9 7 7 X
4 2 4 9 4 8
1 99 4
ALG 2 93 7

6 3 62 8
4 74 9
5
6 88 10
7 82 0
GEO 8 74 1
M1 9 78 0
1 1 74 2
0
84 3
1
INFO LINK
REPRESENTATION OF LINKED LISTS IN MEMORY
 Array representation of multiple lists
BON
D Gra Scot Vit Kat X
nt t o z

KELL
Y Hunt McBri Eva X
er de ns

HAL
L
X

NELSO
N Tell Jone Ada Roge West X
er s ms rs on
REPRESENTATION OF LINKED LISTS IN MEMORY
1 Vito 4
2
3 Hunter 14
4 Katz 0
5
1 BOND 12 6 Evans 0
2 KELLY 3 7
3 HALL 0 8 Rogers 15
4 NELSON 9 9 Teller 10
1 Jones 17
Facult Link 0
y 1
1 Grant 16

1
2 McBride 6
1 Weston 0
3
Scott 1
1
4 Adams 8

1 Stude Link
REPRESENTATION OF LINKED LISTS IN MEMORY
 Representation of lists with multiple data items in each node.

STAR
T Bro 1785210 Fema 1470 Coh 1774445 Male 1900
wn 65 le 0 en 57 0

Davi 1923872 Fema 2280 Eva 1685681 Male 3420 X


s 82 le 0 ns 13 0

1 Evans 1685681 Male 34200 0


2 Cohen 13 Male 19000 4
STAR 3 1774445
T 57
6 4 Davis Femal 22800 1
5 e
1923872
6 Brown 82 14700 2
7 Femal
e
Name 1785210
SSN Sex Salary Link
REPRESENTATION OF LINKED LISTS IN MEMORY
Defining a linked list node
 From the discussion so far, we can conclude that a node
in a list can have any type of data.

 Along with the data, there is a link part that contains the
address/index of the next node.

 The link part will only have integer values as it holds an


address or index, both of which are integers.

 Hence, to define a linked list node, we need to have a


facility by which we can group data belonging to different
data types.
REPRESENTATION OF LINKED LISTS IN MEMORY
 Structures are used to define a linked list node.

 The nodes are then created using dynamic memory


allocation functions.

Defining a node using structures


Consider the following structure definition,
typedef struct node{
char info;
node* link;
};
 The above structure definition results in a node that
holds character data and pointer to another node.
REPRESENTATION OF LINKED LISTS IN MEMORY
Node creation using malloc()
 With the node definition ready, we can now create a
linked list node.

 For this, we first declare a pointer variable as follows,


node* ptr;

 We then use dynamic memory allocation functions to


create a node.
ptr = (node*)malloc(sizeof(node));

Info link
1002
1000 1001 1002 1003 1004 1005 1006
ptr
REPRESENTATION OF LINKED LISTS IN MEMORY
Assigning values to a node
 Once a node has been created, we next need to fill the
node with appropriate values.

 The node that we have created can hold a character in


the info field and address in the link field.

 Here the info and link fields are members of a structure.

 Hence, to assign values to info and link fields, we need


to access these structure members.

 We know that a structure member can be accessed using


a structure variable and the DOT operator.
REPRESENTATION OF LINKED LISTS IN MEMORY
 However, the node that we have created is not
represented by a normal structure variable.

 It is represented by a pointer.
node* ptr;
ptr = (node*)malloc(sizeof(node));

Info link
1002
1000 1001 1002 1003 1004 1005 1006
ptr

 The DOT operator cannot be used by a pointer variable to


access structure members.

 Instead, a special operator, , is used by pointers for this


purpose.
REPRESENTATION OF LINKED LISTS IN MEMORY
 The use of DOT and  is illustrated below. Consider the
structure,
typedef struct sample{
int a;
};
sample var, *ptr;
var . a = 10;
ptr  a = 20;

 We now see how we assign values for the linked list


node using the pointer ptr.
ptr  info = ‘A’;
ptr  link = NULL;
REPRESENTATION OF LINKED LISTS IN MEMORY
 This will result in,
100 A \0
2
ptr
 We now see how to create a linked list of two nodes.
node* create2(){
node *first, *second; 100 A
A 200
2
} first = (node *) 2
firs
malloc(sizeof(node)); t
} second = (node *)
200 B \0
malloc(sizeof(node));
2
secon
} first  info = ‘A’;
d
second  info = ‘B’;
} first  link = second;
} second  link = NULL;
LINKED LIST OPERATIONS
Traversing
Traversing a list involves visiting all the linked list nodes.
05 78 32 19 66 21
0 A 7 B 3 C 1 D 6 E 2 F \0
5 8 2 9 6 1
STAR
T PTR PTR PTR PTR PTR PTR

Algorithm: (Traversing a Linked List) This algorithm visits all


nodes of a linked list, applying an operation PROCESS on each node
of the list. The variable PTR points to the node currently being
processed.
1. Set PTR := START.
2. Repeat steps 3 and 4 while PTR ≠ NULL:
3. Apply PROCESS to PTR  info.
4. Set PTR := PTR  link.
[End of Step 2 loop.]
LINKED LIST OPERATIONS
Algorithm: PRINT(START) This algorithm prints the information at
each node of the list.
1. Set PTR := START.
2. Repeat steps 3 and 4 while PTR ≠ NULL:
3. Write : PTR  info.
4. Set PTR := PTR  link.
[End of Step 2 loop.]
5. Exit

Algorithm: COUNT(START, NUM) This algorithm finds the number


of elements in the list.
1. Set NUM := 0.
2. Set PTR := START.
3. Repeat steps 4 and 5 while PTR ≠ NULL:
4. Set NUM := NUM + 1.
5. Set PTR := PTR  link.
[End of Step 3 loop.]
5. Exit
LINKED LIST OPERATIONS
Searching
Here we will see how a search for an item can be
performed in an ordered and unordered list.

Algorithm: SEARCH(START, ITEM, LOC) This algorithm finds the


location LOC of the node where ITEM first appears in an unordered
linked list, or sets LOC = NULL.
1. Set PTR := START.
2.Repeat steps 3 and 4 while PTR ≠ NULL:
3. If ITEM = PTR  info, then:
Set LOC := PTR and Exit.
Else
Set PTR := PTR  link.
[End of If structure.]
[End of Step 2 loop.]
4. Set LOC := NULL.
5. Exit
LINKED LIST OPERATIONS
Algorithm: SEARCH(START, ITEM, LOC) This algorithm finds the
location LOC of the node where ITEM first appears in an ordered
linked list, or sets LOC = NULL. The list elements are arranged in
descending order.
1. Set PTR := START.
2.Repeat step 3 while PTR ≠ NULL:

3. If ITEM < PTR  info, then:


Set PTR := PTR  link.
Else if ITEM = PTR  info, then:
Set LOC := PTR and Exit.
Else
Set LOC := NULL, and Exit.
[End of If structure.]
[End of Step 2 loop.]

4. Set LOC := NULL.


5. Exit
LINKED LIST OPERATIONS
Insertion
 Different ways of inserting a node in a linked list are:
 Insert at the beginning of the list
 Insert after a specified node
 Insert at the end of the list

Insert at the beginning


This operation is illustrated as follows
100
100 200
200 STEP 1 – Create a new
300
100 A00
1002000 B00
200 \0
300 100 200 node
0
100
STA 0 A0 2000 0 B 0 0 \0
0
300 C 100
300
A 200 B \0 STEP 2 – Make the new
RT
STA
0
STAR 0 0
300
T C0 1000
\0
node point to the
RT
0 current first node.
NEW
STEP 3 - Make START
point to the new node
LINKED LIST OPERATIONS
Function to insert a node at the beginning of a list
1000 2000
3000 A 200 B \0
STAR 0
3000
T
3000 C 100
NEW 0

node* insertBeg(node* START, char


data){
} node* NEW;
NEW =
(node*)malloc(sizeof(node));
NEW  info = data;
} NEW  link = START;
} START = NEW;
LINKED LIST OPERATIONS
Insertion at the end

1000 2000
1000 A 1000
200 B 2000
300
\0 3000
1000
STAR A 2000 B TEMP0
300 C \0
TEMP
T
TEMP
STAR 0 0 3000
T 3000 C \0
NEW

STEP 1 – Create a new node


STEP 2 – Reach the end of the list
STEP 3 – Make TEMP point to the
NEW node
LINKED LIST OPERATIONS
Function to insert a node at the end of a list

1000 2000
1000 A 200 B 300
STAR 0 0
TEMP
T 3000
3000 C \0
NEW

node* insertEnd(node* START,


char data){
} NEW, *TEMP;
node* NEW; TEMP  link =
NEW = NEW;
(node*)malloc(sizeof(node)); return START;
NEW  info = data; }
NEW  link = NULL;
TEMP = START;
} while(TEMP  link != NULL)
LINKED LIST OPERATIONS
Insertion after a specified node

1000 1000 2000 2000 4000 3000


3000
1000
1000 A 200 A 200 B 400 B 400
300 D 300 C C \0 \0
STAR
STAR 0 0 0 0 0
TEMP TEMP
T T
TEMP 4000
4000 D 300\0
NEW 0

STEP 1 – Create a new node


STEP 2 – Reach the specified node
STEP 3 – Make the link field of NEW
node point to the last node.
STEP 4 – Make the link field of TEMP
node point to the NEW node.
LINKED LIST OPERATIONS
Function to insert a node after a specified node

1000 2000 3000


1000 A 200 B 400 C \0
STAR 0 TEMP0
T 4000
4000 D 300
NEW 0

node* insertAfter(node* START, char NEW  link = TEMP 


data, char key){ link;
} node* NEW, *TEMP; TEMP  link = NEW;
NEW = return START;
(node*)malloc(sizeof(node));
NEW  info = data;
NEW  link = NULL;
TEMP = START;
} while(TEMP != NULL){
if(TEMP  info = = key)
break;
LINKED LIST OPERATIONS
Deletion
 Different ways of deleting a node from a linked list are:
 Deleting the first node of the list
 Deleting a specified node
 Deleting the last node of the list

Deleting the first node of the list


STEP 1 – Set a TEMP
pointer to the first
100
200 B
A 300
200 BC 300
\0 C \0 node.
0
STA 0 0 STEP 2 – Make START
TEM
RT P point to the second
node.
STEP 3 – Delete the
node pointed by TEMP
LINKED LIST OPERATIONS
Function to delete the first node of the list

2000
1000 A 200 B 300 C \0
STAR 0
TEMP 0
T

node* deletFront(node*
start){
} node* temp;
temp = start;
} start = start  link;
} free(temp);
return start;
}
LINKED LIST OPERATIONS
Deleting a specified node

1000 2000
3000 3000
1000 200
A 300 C
B \0300 C \0
STAR TEMP0 TEMP0
PREV
T

STEP 1 – Create two pointers TEMP and PREV.


STEP 2 – Set TEMP to START and PREV to NULL..
STEP 3 – Search for the specified node using
TEMP. Also PREV must be one step
behind TEMP.
STEP 4 – Make PREV node point to the node next
to TEMP.
STEP 5 – Delete the node pointed by TEMP.
LINKED LIST OPERATIONS
Function to delete a specified node from the list

1000
1000 2000
3000 3000
1000
1000 AA 300
200
300 B
C 300\0 C \0
STAR 00
TEMP
PREV TEMP 0
STAR
TT
node* deleteSpecific(node
deleteSpecific(node* prev  link = temp 
*start, charkey){
start, char key){ link;
} node *temp, *prev; free(temp);
temp = start; prev = return start;
NULL; }
} while(temp != NULL){
if(temp  info ==
key)
break;
prev = temp;
temp = temp  link;
}
LINKED LIST OPERATIONS
Deleting the last node of the list

1000 2000 3000


1000 A 200 \0
B 300 C \0
STAR 0
TEMP PREV0 TEMP
T
STEP 1 – Create two pointers TEMP
and PREV
STEP 2 – Set TEMP to START and PREV
PREV
to NULL
to NULL
STEP 3 – Reach the end of the list
using TEMP. Also PREV
must be one step before TEMP.
STEP 4 – Delete the node pointed by
TEMP.
STEP 5 – Set the link field of the node
LINKED LIST OPERATIONS
Function to delete the last node from the list

1000
1000 2000
2000 3000
1000
1000 AA 200
200 BB 300
\0
\0 C \0
STAR
STAR TEMP
PREV00 TEMP
PREV0 TEMP
TT
node* deleteEnd(node*
start){
} node *temp, *prev;
temp = start; prev =
= NULL;
NULL;
} while(temp  link !=
NULL){
prev = temp;
temp = temp 
link;
}
} free(temp);
LINKED LIST OPERATIONS
Displaying contents of a list
1000 2000 3000
1000 A 200 B 300 C \0
STAR 0
TEMP 0
TEMP TEMP
T

void display(node *start){


*start){
node *temp;
} node *temp;
temp = start;
temp = start;
while(temp != NULL){
} printf(“%c”,temp 
info);
temp = temp 
link;
}
}
LINKED STACKS AND QUEUES
Linked Stacks
“A Linked Stack is a linear list of elements commonly
implemented as a singly linked list whose start pointer
performs the role of the top pointer of a stack.”

 For a given stack, its corresponding list representation is


presented below.

40 To
p 400 300 200 100
30
400 400 300 200 100 \0
20 0
To
p Linked List representation of the Stack
10

Stack[4
]
LINKED STACKS AND QUEUES
Linked Stack operations
Like in normal stacks, Push and Pop are the operations
that are performed on linked stacks as well.

PUSH
 One difference between normal stacks and linked
stacks is the overflow condition.

 Overflow condition never occurs in linked stacks as the


nodes are dynamically created and the linked stack has
no size defined.

 The Push operation is implemented in linked stack


using the Front Insertion operation.
LINKED STACKS AND QUEUES
3
100
2 200
200
100 10100
0 \0
1 20 To 200TO
0 20 0100 100 \0
p 0 P 0
200
0 10 TOP
To
NE 200 \0
100
p
Stack[4 W 0
]
STEP 1 – STEP 1 – Create a NEW
Increment the node.
value of Top. STEP 2 – Connect the
STEP 2 – Push the NEW node with the
new element at current TOP node.
the current STEP 3 – Make TOP point
position of Top. to the NEW node.
LINKED STACKS AND QUEUES
 The node definition for linked stacks is presented below.

struct node{
int info;
struct node
*link;

};
The Push operation is implemented as follows.

void Push(node *top, int item){


node *new; 200 100
100
new = 200
100 20 0
100 10100\0
0\0
200
(node*)malloc(sizeof(node)); 00 0
TOP
TOP
new -> info = item; 200
new -> link = top; NE 20 0
100
\0
top = new; W 0
}
LINKED STACKS AND QUEUES
POP
Pop operation in linked stacks is implemented using front deletion.

3 TEM
100200P 100
2 0 \0 0100
200
100 1020 100 \0
1 20 To 0 0
TOP
p
0 10 To
p
Stack[4
]
STEP 1 – Print the STEP 1 – Create a TEMP
element pointed pointer. Make TEMP point
by Top. to TOP node.
STEP 2 – STEP 2 – Make TOP point
Decrement the to the next node.
LINKED STACKS AND QUEUES
TEM
100200P 100
200
100 0 \0 0100
1020 100 \0
0 0
TOP

void Pop(node *top){


node *temp;
temp = top;
} top = top -> link;
} printf(“%d”, temp -
> info);
free(temp);
}
LINKED STACKS AND QUEUES
Linked Queues
“A Linked Queue is also a linear list of elements commonly
implemented as a singly linked list but with two pointers i.e.,
FRONT and REAR. The start pointer of the singly linked
list plays the role of FRONT while the pointer to the last
node is set to play the role of REAR.”

Queue[ 20 30 40
4] fro rea
nt r

200 300 400


200 200 300 400 \0
0
Fro Rea
nt r
Linked List representation of the Queue
LINKED STACKS AND QUEUES
Linked Queue Operations
We now look at how Insertion and Deletion operations
are performed on linked queue.

Insertion
Queue[ 200 300 400
4] 200 200 300 \0 400 \0
20 30 40
0
Fro Rea NE
Rea
Rea
fro rea nt r W
rr
nt r
rear
STEP 1 – Create a NEW
STEP 1 – Increment
node.
Rear.
STEP 2 – Make Rear node
STEP 2 – Insert the
point to the NEW node.
new element at
STEP 3 – Make Rear point to
the position
the NEW node.
LINKED STACKS AND QUEUES
200 300 400
200 300 400
200 2000 300 400 \0
200 20 300 \0 400 \0
0
Fro Rea
0
Fro Rea ne
nt r
nt r w

void insert(node *front, int item)


{
} node *new;
new =
(node*)malloc(sizeof(node));
new -> info = item;
new -> link = NULL;
} rear -> link = new;
As can be}seen,rear = new;
queue insertion is implemented in Linked
}
Queues using back insertion.
LINKED STACKS AND QUEUES
Deletion
Since deletion operation in a queue happens from the font end,
deletion in linked queues is implemented using front deletion.

Queue[
300 400
4]
20 30 40 200 300 400
300 200 300 400 \0
300
200 300 400 \0
fro rea 0
0 Fro TEM
Fro Rea
Rea
nt
front r nt r
nt P r
STEP 1 – STEP 1 – Create a TEMP
Increment Front. pointer. Make TEMP point to
STEP 2 – Delete the first node.
the element STEP 2 – Make Front point to
pointed by the second node.
Front. STEP 3 – Delete the TEMP
node.
LINKED STACKS AND QUEUES
300 400
200 300 400
300 200 300 400 \0
300
200 300 400 \0
0
0 Fro TEM
Fro Rea
Rea
nt P r
nt r

void delet(node *front){


node *temp;
temp = front;
} front
front==front
front->
->
link;
} printf(“%d”, temp -
> info);
free(temp);
}
APPLICATION OF LINKED LISTS
Polynomials
 In this section we discuss how polynomials can be
represented using linked lists and how operations like
addition of two polynomials can be performed.

Polynomial Representation
 One condition that must be fulfilled for the representation
is that, the exponents of the given polynomial must be in
the decreasing order.

 Consider the following polynomial of m terms


A(x) = + …. +
Where, are non zero coefficients and are non zero
exponents.
APPLICATION OF LINKED LISTS
 Each term in the polynomial is represented as a linked list
node.

 The node contains the following fields:


 Coefficient
 Exponent
 Pointer to the next term

 A node representing polynomial term is defined as,

struct term{
int coef, expon; expo
coef link
struct term *link; n
}; polyno
typedef struct term de
polynode;
APPLICATION OF LINKED LISTS
 The polynomials
a= + +
b= - +
are represented as follows,
polynode *a, *b;

a 1000 2000 3000


100 3 14 200 2 8 300 1 0 \0
0 0 0

b 4000 5000 6000


400 8 14 500 -3 10 600 10 6 \0
0 0 0
APPLICATION OF LINKED LISTS
Creating a Polynomial polynode* attach(polynode *a){
} polynode *temp, *end;
Consider the polynomial,
temp = (polynode*) malloc
a= + +
(sizeof(polynode));
void main(){ } printf(“enter the coefficient\
polynode *a = NULL; n”);
int n; scanf(“%d”,&temp->coef);
} printf(“enter the number printf(“enter the exponent\
of terms”); n”);
scanf(“%d”,&n); scanf(“%d”,&temp->expon);
for(i=1;i<=n;i++) temp -> link = NULL;
a = attach(a); if(a == NULL)
} } a = temp;
100 200 else{
100 3 1
10020 22 88 30
200
\0 end = a;
4 0 0
NUL
100
a 33 11 20
\0 2 8 \0 while(end -> link !=
end
44 0 NULL)
L
a end
tem end tem 300 end = end -> link;
p temp 1 0 \0 end -> link = temp;
APPLICATION OF LINKED LISTS
Evaluating a polynomial
𝟑𝒙
𝟏𝟒
+ 𝟐𝒙
𝟖
+ 1
x=1
100 200 300 sum = 6
0
sum = 3 (3 * 1^0)
5 + (1
(2 1^8)
100 3 1 20 2 8 30 1 0 \0
1^14)
=6
5 =3
4 0 0
a tem
temp
p temp

int evaluate(polynode *a){ while(temp != NULL){


} polynode *temp; sum = sum + (temp -> coef *
intsum
int sum==0;
0;
if(a == NULL) pow(x,temp->expon);
return 0; temp = temp->next;
} else{ }
temp = a; }
return sum;
} printf(“enter value }}
} x\n”);
of }
scanf(“%d”,&x);
}
APPLICATION OF LINKED LISTS
Addition of two polynomials
Consider the following two polynomials,
a= + +
b= - +

The linked list representation of the above polynomials is,


a 1000 2000 3000
100 3 14 200 2 8 300 1 0 \0
0 0 0

b 4000 5000 6000


400 8 14 500 -3 10 600 10 6 \0
0 0 0

The procedure to add the above two polynomials is presented


next.
APPLICATION OF LINKED LISTS
STEP 1 –Scenario
Create Itwo pointers Scenario II TempB. Make
TempA and Scenario
themIII
- Add to
point coefficients of - Create respectively.
the two polynomials a new node. - Create a new node.
TempA and TempB. - Add the details of - Add the details of
STEP 2 – Compare the exponents of the terms pointed by
Store the result in TempA node in the TempB node in the
TempA and TempB.
a variable sum. There are 3
new node. possible scenarios that can
new node.
emerge.
- Create a new - Insert the new - Insert the new
node.Scenario I: Exponents
Insert sum ofthe
node at both
endterms
of are the
node atsame.
the end of
Scenario
into the II: Exponent
node. Add c. of TempA is greater
c. than
this nodeof
exponent end of - Move TempA to the - Move TempB to the
toTempB.
c. next node.
Scenario III: Exponent next node.
of TempB is greater than
- Move TempA and
exponent
a of TempA.
1000
TempB to the next
2000 3000
TempB to the next
100 3 14 2000 2 8 3000 1 0 \0
nodes.
0 Temp TempA
A TempA
b 4000 5000 6000
400 8 14 5000 -3 10 6000 10 6 \0
0 TempB TempB
c 1100 1200 1300
TempB 1400
110
\0 11 1 1200\0 -3 1 1300
\0 2 8 140
\0 10 6 \0
0 4 0 0
TempC
APPLICATION OF LINKED LISTS
aa 1000
1000 2000
2000 3000
3000
100 3
3 14
14 2000
2000 2
2 8
8 3000
3000 1
1 00 \0
\0
100
00
TempA TempA
TempA

b
b 4000
4000 5000
5000 6000
6000
400
400 8
8 14
14 5000
5000 -3
-3 10
10 6000
6000 10
10 66 \0
\0
0
0 TempB TempB
TempB
TempB

cc 1100
1100 1200
1200 1300
1300 1400
110
NUL
110 11
11 1
11 1 \0
1 1200
1200 -3
-3 1 \0
1 1300
1300 2
2 8
8 \0
\0
140 10 6 \0
0
L0 4
4
4 0
0 0
Temp Temp Temp Temp

end
end
end end
end end

TempA->expon <
>
= TempB-
>expon
END OF
MODULE 2

You might also like