0% found this document useful (0 votes)
11 views16 pages

Data Structures (1) 45 60

The document discusses data structures, specifically stacks and queues, detailing their definitions, operations, and implementations. Stacks operate on a Last In First Out (LIFO) principle with operations like push and pop, while queues operate on a First In First Out (FIFO) principle with enqueue and dequeue operations. It also covers the representation of these structures using arrays and linked lists, along with their applications in programming.

Uploaded by

lavanya.d
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views16 pages

Data Structures (1) 45 60

The document discusses data structures, specifically stacks and queues, detailing their definitions, operations, and implementations. Stacks operate on a Last In First Out (LIFO) principle with operations like push and pop, while queues operate on a First In First Out (FIFO) principle with enqueue and dequeue operations. It also covers the representation of these structures using arrays and linked lists, along with their applications in programming.

Uploaded by

lavanya.d
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

• o Best fit

• o Worst fit

Deallocation schemes: how to return a node to memory bank whenever it is no more required.
• • Random deallocation
• • Ordered deallocation

UNIT-III
STACKS AND QUEUES
STACKS
A Stack is linear data structure. A stack is a list of elements in which an element may be
inserted or deleted only at one end, called the top of the stack. Stack principle is LIFO (last in,
first out). Which element inserted last on to the stack that element deleted first from the stack.
As the items can be added or removed only from the top i.e. the last item to be added to a stack
is the first item to be removed.

Operations on stack:
The two basic operations associated with stacks are:
1. Push
2. Pop
While performing push and pop operations the following test must be conducted on the stack.
a) Stack is empty or not b) stack is full or not
1. Push: Push operation is used to add new elements in to the stack. At the time of addition first
check the stack is full or not. If the stack is full it generates an error message "stack overflow".
2. Pop: Pop operation is used to delete elements from the stack. At the time of deletion first
check the stack is empty or not. If the stack is empty it generates an error message "stack
underflow".
All insertions and deletions take place at the same end, so the last element added to the
stack will be the first element removed from the stack. When a stack is created, the stack base
remains fixed while the stack top changes as elements are added and removed. The most
accessible element is the top and the least accessible element is the bottom of the stack.
Representation of Stack (or) Implementation of stack:
The stack should be represented in two ways:
1. Stack using array
2. Stack using linked list
1. Stack using array:

Let us consider a stack with 6 elements capacity. This is called as the size of the stack. The
number of elements to be added should not exceed the maximum size of the stack. If we
attempt to add new element beyond the maximum size, we will encounter a stack overflow
condition. Similarly, you cannot remove elements beyond the base of the stack. If such is the
case, we will reach a stack underflow condition.

1. push():When an element is added to a stack, the operation is performed by push().


Below Figure shows the creation of a stack and addition of elements using push().

Initially top=-1, we can insert an element in to the stack, increment the top value i.e top=top+1.
We can insert an element in to the stack first check the condition is stack is full or not. i.e
top>=size-1. Otherwise add the element in to the stack.
void push()
{
int x; Algorithm: Procedure for push():
if(top >= n-1) Step 1: START
{ Step 2: if top>=size-1 then
printf("\n\nStack Overflow.."); Write “ Stack is
return; Overflow” Step 3:
} Otherwise
else 3.1 : read data value ‘x’
{ 3.2 : top=top+1;
printf("\n\nEnter data: "); 3.3 : stack[top]=x;
scanf("%d", &x); Step 4: END
stack[top] = x;
top = top + 1;
printf("\n\nData Pushed into the stack");
}
}

2. Pop(): When an element is taken off from the stack, the operation is performed by pop().
Below figure shows a stack initially with three elements and shows the deletion of
elements using pop().
We can insert an element from the stack, decrement the top value i.e top=top-1. We can delete an
element from the stack first check the condition is stack is empty or not. i.e top==-1. Otherwise
remove the element from the stack.

Void pop() Algorithm: procedure pop():


{ Step 1: START
If(top==-1) Step 2: if top==-1 then Write
{ “Stack is Underflow” Step
Printf(“Stack is Underflow”); 3: otherwise
} 3.1 : print “deleted element”
else 3.2 : top=top-1;
{ Step 4: END
printf(“Delete data %d”,stack[top]);
top=top-1;
}
}
3. display(): This operation performed display the elements in the stack. We display the element
in the stack check the condition is stack is empty or not i.e top==-1.Otherwise display the list of
elements in the stack.
void display() Algorithm: procedure pop():
{ Step 1: START
If(top==-1) Step 2: if top==-1 then Write
{ “Stack is Underflow” Step
Printf(“Stack is Underflow”); 3: otherwise
} 3.1 : print “Display elements are”
else 3.2 : for top to 0
{ Print ‘stack[i]’
printf(“Display elements are:); Step 4: END
for(i=top;i>=0;i--)
printf(“%d”,stack[i]);
}
}

Source code for stack operations, using array:


#include<stdio.h>
#inlcude<conio.h>
int stack[100],choice,n,top,x,i;
void push(void);
void pop(void); void
display(void); int
main()
{
//clrscr();
top=-1;
printf("\n Enter the size of STACK[MAX=100]:");
scanf("%d",&n);
printf("\n\t STACK OPERATIONS USING ARRAY");
printf("\n\t ");
printf("\n\t 1.PUSH\n\t 2.POP\n\t 3.DISPLAY\n\t 4.EXIT");
do
{
printf("\n Enter the Choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
push();
break;
}
case 2:
{
pop();
break;
}
case 3:
{
display();
break;
}
case 4:
{
printf("\n\t EXIT POINT ");
break;
}
default:
{
printf ("\n\t Please Enter a Valid Choice(1/2/3/4)");
}
}
}
while(choice!=4);
return 0;
}
void push()
{
if(top>=n-1)
{
printf("\n\tSTACK is over flow");
}
else
{
printf(" Enter a value to be pushed:");
scanf("%d",&x);
top++;
stack[top]=x;
}
}
void pop()
{
if(top<=-1)
{
printf("\n\t Stack is under flow");
}
else
{
printf("\n\t The popped elements is
%d",stack[top]); top--;
}
}
void display()
{
if(top>=0)
{
printf("\n The elements in STACK \n");
for(i=top; i>=0; i--)
printf("\n%d",stack[i]); printf("\
n Press Next Choice");
}
else
{
printf("\n The STACK is empty");
}
}
2. Stack using Linked List:
We have seen how a stack is created using an array. This technique of creating a stack is easy,
but the drawback is that the array must be declared to have some fixed size. In case the stack is
a very small one or its maximum size is known in advance, then the array implementation of
the stack gives an efficient implementation. But if the array size cannot be determined in
advance, then the other alternative, i.e., linked representation, is used.
The storage requirement of linked representation of the stack with nelements is O(n), and
the typical time requirement for the operations is O(1).
In a linked stack, every node has two parts—one that stores data and another that stores the
address of the next node. The START pointer of the linked list is used as TOP. All insertions and
deletions are done at the node pointed by TOP. If TOP = NULL, then it indicates that the stack is
empty.
The linked representation of a stack is shown in Fig. 7.13.
9 1 7 3 4 2 6 5 X
TOP

Figure 7.13 Linked stack


OPERATIONS ON A LINKED STACK
A linked stack supports all the three stack operations, that is, push, pop, and peek.

Push Operation
The pushoperation is used to insert an element into the stack. The new element is added at the
topmost position of the stack. Consider the linked stack shown in Fig. 7.14.
1 7 3 4 2 6 5 X
TOP

Figure 7.14 Linked stack

To insert an element with value 9, we first check if TOP=NULL. If this is the case, then we
allocatememory for a new node, store the value in its DATA part and NULL in its NEXT part. The
new node will then be called TOP. However, if TOP!=NULL, then we insert the new node at the
beginning of the linked stack and name this new node as TOP. Thus, the updated stack becomes
as shown in Fig. 7.15.
9 1 7 3 4 2 6 5 X
TOP

Figure 7.15 Linked stack after inserting a new node

Figure 7.16 shows the algorithm to push an element into a linked stack. In Step 1, memory
is allocated for the new node. In Step 2, the DATApart of the new node is initialized with the
value tobe stored in the node. In Step 3, we check if the new node is the first node of the linked
list.

Step 1: Allocate memory for the new node and name it as

NEW_NODE Step 2: SET NEW_NODE DATA = VALStep 3: IF

TOP = NULL

SET NEW_NODE NEXT = NULLSET TOP = NEW_NODE

ELSE

SET NEW_NODE NEXT = TOPSET TOP =

NEW_NODE [END OF IF]

Step 4: END

Figure 7.16 Algorithm to insert an element in alinked stack

This is done by checking if TOP = NULL. In case the IFstatementevaluates to true, then NULLis stored in
the NEXTpart of thenode and the new node is called TOP. However, if the newnode is not the first node
in the list, then it is added beforethe first node of the list (that is, the TOP node) and termedas TOP.

7.1.1 Pop Operation


The popoperation is used to delete the topmost element from astack. However, before deleting the value,
we must first checkif TOP=NULL, because if this is the case, then it means that thestack is empty and no
more deletions can be done. If an attempt is made to delete a value from a stack that is already
empty, an UNDERFLOWmessage is printed. Consider the stack shown in Fig. 7.17.

9 1 7 3 4 2 6 5 X
TOP

Figure 7.17 Linked stack

In case TOP!=NULL, then we will delete the node pointed by TOP, and make TOPpoint to the
second element of the linked stack. Thus, the updated stack becomes as shown in Fig. 7.18.

1 7 3 4 2 6 5 X
Top

Figure 7.18 Linked stack after deletion of the topmost element

Step 1: IF TOP = NULL

PRINT "UNDERFLOW"

Goto Step 5[END OF IF]

Step 2: SET PTR = TOP

Step 3: SET TOP = TOP NEXTStep 4: FREE PTR

Step 5: END

Figure 7.19 Algorithm to delete an element from a linked stack

Figure 7.19 shows the algorithm to delete an element froma stack. In Step 1, we first check
for the UNDERFLOW condition. In Step 2, we use a pointer PTR that points to TOP. In Step 3, TOP is
made to point to the next node in sequence. In Step 4, the memory occupied by PTR is given back to
the free pool.

Applications of stack:
1. Stack is used by compilers to check for balancing of parentheses, brackets and braces.
2. Stack is used to evaluate a postfix expression.
3. Stack is used to convert an infix expression into postfix/prefix form.
4. In recursion, all intermediate arguments and return values are stored on the
processor’s stack.
5. During a function call the return address and arguments are pushed onto a stack and
on return they are popped off.
QUEUE:
A queue is linear data structure and collection of elements. A queue is another special kind of list,
where items are inserted at one end called the rear and deleted at the other end called the front.
The principle of queue is a “FIFO” or “First-in-first-out”.
Queue is an abstract data structure. A queue is a useful data structure in programming. It is
similar to the ticket queue outside a cinema hall, where the first person entering the queue is
the first person who gets the ticket.
A real-world example of queue can be a single-lane one-way road, where the vehicle enters first,
exits first.
More real-world examples can be seen as queues at the ticket windows and bus-stops and our
college library.
The operations for a queue are analogues to those for a stack; the difference is that the insertions
go at the end of the list, rather than the beginning.
Operations on QUEUE:
A queue is an object or more specifically an abstract data structure (ADT) that allows the
following operations:
Enqueue or insertion: which inserts an element at the end of the queue.
Dequeue or deletion: which deletes an element at the start of the queue.

Queue operations work as follows:


1. Two pointers called FRONT and REAR are used to keep track of the first and last elements
in the queue.
2. When initializing the queue, we set the value of FRONT and REAR to 0.
3. On enqueing an element, we increase the value of REAR index and place the new element in
the position pointed to by REAR.
4. On dequeueing an element, we return the value pointed to by FRONT and increase the
FRONT index.
5. Before enqueing, we check if queue is already full.
6. Before dequeuing, we check if queue is already empty.
7. When enqueing the first element, we set the value of FRONT to 1.
8. When dequeing the last element, we reset the values of FRONT and REAR to 0.
Representation of Queue (or) Implementation of Queue:
The queue can be represented in two ways:
1. Queue using Array
2. Queue using Linked List

1. Queue using Array:


Let us consider a queue, which can hold maximum of five elements. Initially the queue is
empty.

Now, insert 11 to the queue. Then queue status will be:


Next, insert 22 to the queue. Then the queue status is:

Again insert another element 33 to the queue. The status of the queue is:

Now, delete an element. The element deleted is the element at the front of the queue.So the
status of the queue is:

Again, delete an element. The element to be deleted is always pointed to by the FRONT
pointer. So, 22 is deleted. The queue status is as follows:

Now, insert new elements 44 and 55 into the queue. The queue status is:

Next insert another element, say 66 to the queue. We cannot insert 66 to the queue as the rear
crossed the maximum size of the queue (i.e., 5). There will be queue full signal. The queue
status is as follows:
Now it is not possible to insert an element 66 even though there are two vacant positions in the
linear queue. To overcome this problem the elements of the queue are to be shifted towards the
beginning of the queue so that it creates vacant position at the rear end. Then the FRONT and
REAR are to be adjusted properly. The element 66 can be inserted at the rear end. After this
operation, the queue status is as follows:

This difficulty can overcome if we treat queue position with index 0 as a position that comes
after position with index 4 i.e., we treat the queue as a circular queue.
Queue operations using array:
a.enqueue() or insertion():which inserts an element at the end of the queue.
void insertion() Algorithm: Procedure for insertion():
{ Step-1:START
if(rear==max) Step-2: if rear==max then
printf("\n Queue is Full"); Write ‘Queue is full’
else Step-3: otherwise
{ 3.1: read element ‘queue[rear]’
printf("\n Enter no %d:",j++); Step-4:STOP
scanf("%d",&queue[rear++]);
}
}
b.dequeue() or deletion(): which deletes an element at the start of the queue.
void deletion() Algorithm: procedure for deletion():
{ Step-1:START
if(front==rear) Step-2: if front==rear then
{ Write’ Queue is empty’
printf("\n Queue is empty"); Step-3: otherwise
} 3.1: print deleted element
else Step-4:STOP
{
printf("\n Deleted Element is
%d",queue[front++]); x+
+;
}}

Queue using Linked list:


We have seen how a queue is created using an array. Although this technique of creating a queue
is easy, its drawback is that the array must be declared to have some fixed size. If we allocate
space for 50 elements in the queue and it hardly uses 20–25 locations, then half of the space
will
be wasted. And in case we allocate less memory locations for a queue that might end up
growing large and large, then a lot of re-allocations will have to be done, thereby creating a lot
of overhead and consuming a lot of time.
In case the queue is a very small one or its maximum size is known in advance, then the
array implementation of the queue gives an efficient implementation. But if the array size
cannot be determined in advance, the other alternative, i.e., the linked representation is used.
The storage requirement of linked representation of a queue with n elements is O(n) and the
typical time requirement for operations is O(1).
In a linked queue, every element has two parts, one that stores the data and another that
stores the address of the next element. The STARTpointer of the linked list is used as FRONT.
Here, we willalso use another pointer called REAR, which will store the address of the last
element in the queue.All insertions will be done at the rear end and all the deletions will be
done at the front end. If FRONT=REAR=NULL, then it indicates that the queue is empty.
The linked representation of a queue is shown in Fig. 8.6.
Operations on Linked Queues
A queue has two basic operations: insert and delete. The insert operation adds an element to the end
of the queue, and the delete operation removes an element from the front or the start ofthe queue.
Apart from this, there is another operation peek which returns the value of the first element of
the queue.
Insert Operation

The insert operation is used to insert an element into a queue. The new element is added as the
last element of the queue. Consider the linked queue shown in Fig. 8.7.
To insert an element with value 9, we first
9 1 7 3 4 2 6 5 X
check if FRONT=NULL. If the condition holds,
then
Front Rear
the queue is empty. So, we allocate memory
Figure 8.6 Linked queue for a new node, store the value in its DATA
part and NULL in its NEXT part. The new node
1 7 3 4 2 6 5 X will then becalled both FRONT and REAR.
However, if FRONT
Front Rear != NULL, then we will insert the new node at
the rear end of the linked queue and name this
Figure 8.7 Linked queue
new

9 X
node as REAR. Thus, the updated queue becomes
1 7 3 4 2 6 5
Front Rear

Figure 8.8 Linked queue after inserting a new node

Step 1: Allocate memory for the new node and nameit as

PTR Step 2: SET PTR  DATA = VALStep 3: IF FRONT =


NULL

SET FRONT = REAR = PTR

SET FRONT  NEXT = REAR  NEXT = NULL

ELSE

SET REAR  NEXT = PTRSET REAR =

PTR SET REAR  NEXT = NULL[END OF

IF]

Step 4: END

Figure 8.9 Algorithm to insert an element in a linked queue

Figure 8.9 shows the algorithm to insertan element in a linked queue. In Step 1, the memory is
allocated for the new node. In Step2, the DATA part of the new node is initialized with the value to be
stored in the node. In Step 3, we check if the new node is the first node of the linked queue. This is
done by checking if FRONT = NULL. If this is the case, then the new node is tagged as FRONT as well as
REAR. Also NULL is stored in the NEXT part of the node (which is also the FRONT and the REAR node).
However, ifthe new node is not the first node in the list, thenit is added at the REAR end of the linked
queue (or the last node of the queue).
Delete Operation:

The delete operation is used to delete the element that is first inserted in a queue, i.e., the
element whose address is stored in FRONT. However, before deleting the value, we must first
check if FRONT=NULL because if this is the case, then the queue is empty and no more
deletions can be
9 1 7 3 4 2 6 5 X
done. If an attempt is made to delete a value
from a queue that is already empty, an underflow
Front Rear
message is printed. Consider the queue shown
Figure 8.10 Linked queue in Fig. 8.10.
To delete an element, we first check if
1 7 3 4 2 6 5 X
Front Rear FRONT=NULL. If the condition is false, then
we

Figure 8.11 Linked queue after deletion of an element delete the first node pointed by FRONT. The
FRONT

will now point to the second element of the


Step 1: IF FRONT = NULL

Write "Underflow"

Go to Step 5[END OF IF]

Step 2: SET PTR = FRONT

Step 3: SET FRONT = FRONT  NEXTStep 4: FREE PTR

Step 5: END

Figure 8.12 Algorithm to delete an element from a linked queue

linked queue. Thus, the updated queue becomes as shown in Fig. 8.11.

Figure 8.12 shows the algorithm to delete an element froma linked queue. In Step 1, we first check for the
condition. If the condition is true, then an appropriate messageis displayed, otherwise in Step 2, we
underflow
use a pointer PTR that points to FRONT. In Step 3, FRONT is made to point to the next node in sequence. In Step
4, the memory occupied by PTR is given back to the free pool.

Applications of Queue:
1. It is used to schedule the jobs to be processed by the CPU.
2. When multiple users send print jobs to a printer, each printing job is kept in the printing
queue. Then the printer prints those jobs according to first in first out (FIFO) basis.
3. Breadth first search uses a queue data structure to find an element from a graph.

Scheduling :

The processes that are entering into the system are stored in the Job Queue. Suppose if the processes
are in the Ready state are generally placed in the Ready Queue.

The processes waiting for a device are placed in Device Queues. There are unique device queues
which are available for every I/O device.

First place a new process in the Ready queue and then it waits in the ready queue till it is selected for
execution.

Once the process is assigned to the CPU and is executing, any one of the following events occur −

 The process issue an I/O request, and then placed in the I/O queue.
 The process may create a new sub process and wait for termination.
 The process may be removed forcibly from the CPU, which is an interrupt, and it is put back
in the ready queue.
In the first two cases, the process switches from the waiting state to the ready state, and then puts it back
in the ready queue. A process continues this cycle till it terminates, at which time it is removed from
all queues and has its PCB and resources deallocated.

Types of Schedulers

There are three types of schedulers available which are as follows −

Long Term Scheduler

Long term scheduling is performed when a new process is created, if the number of ready processes in
the ready queue becomes very high. Then, there is an overhead on the operating system, for
maintaining long lists, containing switching and dispatching increases. Therefore, allowing only a
limited number of processes into the ready queue, the long term scheduler manages this.

Long term scheduler runs less frequently. It decides which program must get into the job queue. From
the job queue, the job processor selects processes and loads them into the memory for execution.

The main aim of the Job Scheduler is to maintain a good degree of Multiprogramming. The degree of
Multiprogramming means the average rate of process creation is equal to the average departure rate of
processes from the execution memory.

The diagram of long term and short term scheduler is as follows −


Short Term Scheduler

Short term scheduler is called a CPU Scheduler and runs very frequently. The aim of the scheduler is
to enhance CPU performance and increase process execution rate.

Medium Term Scheduler

This type of scheduling removes the processes from memory and thus reduces the degree of
multiprogramming. Later, the process is reintroduced into memory and its execution is continued
where it left off. This is called swapping. The process is swapped out, and is later swapped in, by the
medium term scheduler.

The diagram of medium term scheduler is as follows −

You might also like