0 ratings0% found this document useful (0 votes) 30 views30 pagesBest Stack and Queue
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here.
Available Formats
Download as PDF or read online on Scribd
Data Structures
UNIT-2
Stack & QueueData Structures
13. Stack
A stack is_an Abstract Data Type (ADT), commonly used in most programming
languages. It is named stack as it behaves like a real-world stack, for example ~ a deck
of cards or a pile of plates, etc.
‘A real-world stack allows operations at one end only. For example, we can place or
remove a card or plate from the top of the stack only. Likewise, Stack ADT allows all
data operations at one end only, At any given time, we can only access the top element
of a stack.
This feature makes it LIFO data structure. LIFO stands for Last-in-first-out. Here, the
element which is placed (inserted or added) last, is accessed first. In stack terminology,
insertion operation is called PUSH operation and removal operation is called POP
operation.
Stack Representation
The following diagram depicts a stack and its operations —
2, Last In - First Out
Push Pop
‘Data Boment sta Element
‘Bata Element ‘Data Element
ata Bement ata Element
‘Data Bement ata Bement
ata Dement ata Eomont
Stack Stack
A stack can be implemented by means of Array, Structure, Pointer, and Linked List. Stack can
either be a fixed size one or it may have a sense of dynamic resizing. Here, we are going to
Implement stack using arrays, which makes it a fixed size stack implementation.
60Data Structures
Basic Operations
Stack operations may involve initializing the stack, using it and then de-initializing it.
Apart from these basic stuffs, a stack is used for the following two primary operations —
+ push() ~ Pushing (storing) an element on the stack.
* pop() — Removing (accessing) an element from the stack.
When data is PUSHed onto stack.
To use a stack efficiently, we need to check the status of stack as well, For the same
purpose, the following functionality is added to stacks —
* peek() — get the top data element of the stack, without removing it.
+ isFull() ~ check if stack is full
+ isEmpty() ~ check if stack is empty.
At all times, we maintain a pointer to the last PUSHed data on the stack. As this pointer
always represents the top of the stack, hence named top. The top pointer provides top
value of the stack without actually removing it
First we should learn about procedures to support stack functions -
peek()
Algorithm of peek() function
begin procedure peek
return etack{top]
end procedure
Implementation of peek() function in C programming language —
int peak() {
return stack(top];
61Data Structures
isfull()
Algorithm of isfull() function -
begin procedure isfull
Sf top equals to MAXSIZE
return true
else
return
false endif
end procedure
Implementation of isfull() function in C programming language ~
bool isfull() {
if(top == MAXSIZE)
return true;
else
return fale;
isempty()
Algorithm of isempty() function —
begin procedure isenpty
if top Less than 2
return true
else
return
faise endif
end procedure
62Data Structures
Implementation of isempty() function in C programming language is slightly different.
We initialize top at -1, as the index in array starts from 0. So we check if the top is
below zero or -1 to determine if the stack is empty. Here's the code —
bool isenpty() {
a)
return tru
S¢(top
alse
return false;
Push Operation
The process of putting a new data element onto stack is known as a Push Operation.
Push operation involves a series of steps —
# Step 1 — Checks if the stack is full.
+ Step 2 — If the stack is full, produces an error and exit.
+ Step 3 ~ If the stack is not full, increments top to point next empty space.
+ Step 4 — Adds data element to the stack location, where top is pointing
+ Step 5 — Returns success.
E Push Operation
top ——
63Data Structures
If the linked list is used to implement the stack, then in step 3, we need to allocate
space dynamically.
Algorithm for PUSH Operation
‘A simple algorithm for Push operation can be derived as follows —
begin procedure push: stack, data
if stack is full
return null
endif
top + top +1
stack[top] + data
end procedure
Implementation of this algorithm in C, is very easy. See the following code —
void push(int data) {
sf(IdeFULL()) {
top = top + 3;
stack[top] = deta;
jelse {
print#("could not insert data, Stack is full.\n");
Pop Operation
Accessing the content while removing it from the stack, is known as a Pop Operation. In
an array implementation of pop() operation, the data element is not actually removed,
instead top is decremented to a lower position in the stack to point to the next value.
But in linked-list implementation, pop() actually removes data element and deallocates
memory space.
A Pop operation may involve the following steps —
+ Step 1 - Checks if the stack is empty.
+ Step 2 ~ if the stack is empty, produces an error and exit.
64Data Structures
+ Step 3 ~ If the stack is not empty, accesses the data element at which top is
pointing
+ Step 4 — Decreases the value of top by 1.
+ Step 5 — Returns success,
Pop Operation
Stack
Algorithm for Pop Operation
A simple algorithm for Pop operation can be derived as follows —
begin procedure pop: stack
Af stack is empty
retuen null
endif
data « stack{top]
top + top - 2
return data
fend procedure
6Data Structures
Implementation of this algorithm in C, is as follows —
ine pop(int data) {
if(lisempty()) {
data = stack{top];
top = top - 2;
return dat
jelse {
printf("Could not retrieve data, Stack is empty.\n")3
}
For a complete stack program in C programming language, please click here,
Stack Program in C
We shall see the stack implementation in C programming language here. You can try the
program by clicking on the Try-it button. To learn the theory aspect of stacks, click on
visit previous page.
Implementation in C
#include
int naxsize
int steck{8];
int top = -15
int isempty() {
if(top == -1)
return 43
else
return 85
66Data Structures
int isfull() (
Sf(top == MAXSIZE)
return 15
else
return 85
>
int peek() {
return stack[top];
>
nt pop) {
int datas
if(Lisempty()) {
data = stack{top];
top = top - 2
return di
jeise {
printf("Could not retrieve data, Stack is empty.\n");
int push(int data) {
af(1isfuldQ) ¢
top = top +45
stack [top]
date; }else {
printf("could not insert data, Stack is full. \n");
67Data Structures
int main() {
1/ push stens on to the
stack push(3);
push(5)5
push(3) 5
push(2) 5
push(12)3
push(35);
print#(“Elenent at top of the stack: %d\n" ,peek());
print#("Elements: \n");
// print stack data
whdle(lisempty()) {
int data = pop();
printf("%d\n", data);
print#("Stack full: s\n" , isfull()?"true":"felse");
'False");
printf("stack empty: s\n" , isempty()?"tru
return 95
If we compile and run the above program, it will produce the following result —
Elenent at top of the stack: 15
Elenents:
6
n
1
°
5
3
stack full: false
[Stack empty: true
t
68Data Structures
15. Queue
Queue is an abstract data structure, somewhat similar to Stacks. Unlike stacks, a queue
iS open at both its ends. One end is always used to insert data (enqueue) and the other
is used to remove data (dequeue). Queue follows First-In-First-Qut methodology, i.e.,
the data item stored first will be accessed first.
stn FRSTIN
.astour aS FIRST OUT
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.
Queue Representation
‘As we now understand that in queue, we access both ends for different reasons. The
following diagram given below tries to explain queue representation as data structure -
_ = =a
In Data Data Data Data Data Data ‘Out
a
Last in Last out Firat in Fret Out
Queue
As in stacks, a queue can also be implemented using Arrays, Linked-lists, Pointers and
Structures. For the sake of simplicity, we shall implement queues using one-dimensional
array,
Basic Operations
Queue operations may involve initializing or defining the queue, utilizing it, and then
completely erasing it from the memory. Here we shall try to understand the basic
operations associated with queues ~
+ enqueue() ~ add (store) an item to the queue.
+ dequeue() — remove (access) an item from the queue.
69Data Structures
Few more functions are required to make the above-mentioned queue operation efficient.
These are —
+ peek() — Gets the element at the front of the queue without removing It.
isfull() — Checks if the queue is full
isempty() ~ Checks if the queue is empty.
In queue, we always dequeue (or access) data, pointed by front pointer and while
enqueing (or storing) data in the queue we take help of rear pointer.
Let's first learn about supportive functions of a queue —
peek()
This function helps to see the data at the front of the queue. The algorithm of peek()
function is as follows —
begin procedure peek
return queue[front]
end procedure
Implementation of peek() function in C programming language —
int peek() {
return queue[front];
}
isfull()
‘As we are using single dimension array to implement queue, we just check for the rear
pointer to reach at MAXSIZE to determine that the queue Is full. In case we maintain the
Queue in a circular linked-list, the algorithm will differ. Algorithm of isfull() function —
begin procedure isfull
Lf pear equals to MAXSIZE
return true
else
70Data Structures
Feturn false
enaif
end procedure
Implementation of isfull() function in C programming language ~
boot isfull() {
if(rear == MAXSIZE - 1)
return true;
else
return false;
isempty()
Algorithm of isempty() function —
begin procedure isempty
if front is lees than MIN OR front dz greater than rear
return true
alse
return
False endif
fend procedure
If the value of front is less than MIN or 0, it tells that the queue is not yet initialized,
hence empty.
Here's the C programming code —
bool isempty() ¢
if(front < @ || front > rear)
return true;
else
return false;
71Data Structures
Enqueue Operation
Queues maintain two data pointers, front and rear. Therefore, its operations are
comparatively difficult to implement than that of stacks.
The following steps should be taken to enqueue (insert) data into a queue —
+ Step 1 ~ Check if the queue is full
+ Step 2 — If the queue is full, produce overfiow error and exit.
+ Step 3 - If the queue is not full, increment rear pointer to point the next empty
space.
+ Step 4 - Add data element to the queue location, where the rear is pointing.
+ Step 5 — Return success.
Rear Front
nN ¢ 8 A before
Rear Front
t+ to.
D c 8 A after
Queue Enqueue
Sometimes, we also check to see if a queue is initialized or not, to handle any
unforeseen situations.
72Data Structures
Algorithm for enqueue Operation
procedure enqueue (data)
if queue is full
return
overflow endif
rear e rear +2
queve[rear] = data
return true
fend procedure
Implementation of enqueue() in C programming language —
int enqueue(int data)
if(istullQ)
return 95
rear = rear + 15
queuefrear] = data;
return 2;
end procedure
Dequeue Operation
‘Accessing data from the queue is a process of two tasks — access the data where front
is pointing and remove the data after access, The following steps are taken to perform
dequeue operation -
+ Step 1 - Check if the queue is empty.
+ Step 2 — If the queue is empty, produce underflow error and exit.
+ Step 3 — If the queue is not empty, access the data where front is pointing.
+ Step 4 — Increment front pointer to point to the next available data element.
+ Step 5 — Return success.
73Data Structures
Rear Front
tea 4
betore (Ee) Ee 8 A
Rear Front
—————
after > c 8
, Queue
Queue Dequeue
Algorithm for dequeue Operation
procedure dequeue if
queue is empty
return
underflow end if
data = queve(front]
front © front +1
return true
end procedure
Implementation of dequeue() in C programming language —
Ant dequeve() {
if (isempty())
return 8;
int data = queue[front];
front = front + 13
return dates
74Data Structures
Queue Program in C
We shall see the stack implementation in C programming language here. You can try the
program by clicking on the Try-it button. To learn the theory aspect of stacks, click on
visit previous page.
Implementation in C
#include
include
#include
include
define MAX 6
int intarray[Mex];
int front = @;
int re
Pe oa
int itencount = @;
int peek(){
return intarray[ front];
bool istmpty(){
return itemcount == 0;
}
bool isFull(C
return dtemcount == MAX;
int size(){
return itencount;
void insert (int data){
AF(ISFULLO)
75Data Structures
iF(rear
4){ rear = -15
intAray[++rear] = data;
Atemcounts+;
int renovedata(){
int data = intarray[fronte+];
iF (Front
Front
?
itencount--;
Max)
8
retuen data;
int main() {
/* insert 5 Stems */
insert(3)5,
insert(5);
insert(9) 5
Ansere(a);
insert(32)5
1) Front + 8
I) rear
We
Uf index: 01234
We
df queue: 3592
12 insert (15);
Uf Front + @
Uf rear: 5
76Data Structures
ie
Jf index 202234 5
53592215
if (4sFuLLOM
print#("queue is full!\n");
U/ venove one item
int nun = removeData();
print#("Elenent removed: %d\n", num) ;
UI Front: 1
df vear 3 5
Ue a
Uf index 21234 5
We -
J/ queue : 5921215
I) insert nore
items insert(16);
I) front: 1
J vear
uw
Uf index 2 @12345//
J/ queue : 185911215
J/ As queue is full, elements will not be
inserted. insert(17)3
insert(28);
We
Uf index 2 @22345 //
7Data Structures
// queue : 16 5 91 12 15 print#(“Elenent
at Front: fe\n".peek())s
printf (
\n"
e\n"
printf("index : 54.322
5 printe(” =
\n"); print #("Queve
while(!istmpty())4
int n = renovepata();
printf("xd *5n)3
If we compile and run the above program, it will produce the following result —
Qqueve is full!
Element renoved: 3
Element at front: 5
index: 543220
Qqueve: $9112 15 16
78Data Structures
Hash Table
Hash Table is a data structure which stores data in an associative manner. In a
hash table, data is stored in an array format, where each data value has its own unique
index value, Access of data becomes very fast if we know the index of the desired data.
Thus, it becomes a data structure in which insertion and search operations are very fast
irrespective of the size of the data. Hash Table uses an array as a storage medium and
uses hash technique to generate an index where an element is to be inserted or is to be
located from.
Hashing
Hashing is a technique to convert a range of key values into a range of indexes of an
array. We're going to use modulo operator to get a range of key values. Consider an
example of hash table of size 20, and the following items are to be stored. Item are in
the (key, value) format.
(=n
EO
+ (1,20)
+ (2,70)
+ (42,80)
+ (4,25)
+ (12,44)
© (14,32)
+ a7an
+ (13,78)
+ (37,98)
79Data Structures
Sr.No. Key Hash ‘Array Index
T T T%20=1 x
z z 2% 20=2 z
3 co) 42% 20 = z
z z 4% 20=4 a
3 iz 12% 20= 12 1
6 cry 14% 20= 14 cry
7 7 17% 20= 17 7
z 3 13% 20= 15 is
3 7 37% 20= 17 7
Linear Probing
As we can see, it may happen that the hashing technique is used to create an already used
index of the array. In such 2 case, we can search the next empty location in the array by
looking into the next cell until we find an empty cell. This technique is called linear probing.
‘After Linear
Sr.No. key Hash Array Index | Probing,
Array Index
T T T%20=1 T T
zi 2 2% 20=2 2 2
3 a AZO =2 z 3
4 a 4% 20-4 q 4
5 iz 12% 20= 12 TZ iz
6 7 14% 20= 14 17 7
80Data Structures
7 7 17% 20= 17 7 7
3 ri 13% 20 = 13 1s Ts
3 7 37% 20 = 17 17 is
Basic Operations
Following are the basic primary operations of a hash table,
+ Search ~ Searches an element in a hash table.
+ Insert ~ inserts an element in a hash table.
+ Delete ~ Deletes an element from a hash table,
Data Item
Define a data item having some data and key, based on which the search is to be
conducted in a hash table.
struct Dataltem {
int data;
int keys
i
Hash Method
Define @ hashing method to compute the hash code of the key of the data item,
int hashCode(int key)(
return key % SIZE;
Search Operation
Whenever an element is to be searched, compute the hash code of the key passed and
locate the element using that hash code as index in the array. Use linear probing to get
the element ahead if the element is not found at the computed hash code,
81Data Structures
struct Datalten *search(int key){
//gst the hash
int hashIndex = hashCode(key)
//move in erray until an empty
while(hazhaeray[hashindex) [= NULL)
At(hashanray[hachindex]->key == key)
retuen hashArray [hashIndex];
(qo to next cell
sthachindex;
(Jweap around the table
hashIndex %= SIZE;
return NULL
Insert Operation
Whenever an element is to be inserted, compute the hash code of the key passed and
locate the index using that hash code as an index in the array. Use linear probing for
empty location, if an element is found at the computed hash code.
void insert (int key,int data){
struct DataTtem ‘item = (struct Datatten*) malloc(sizeof(struct
Datartem)); iten->data = data;
tem->key = key;
//gt the hash
int hashIndex = hashCode(key);
//move in array until an enpty or deleted cell while(hasharray[hashindex]
2)t
l= NULL && hacharray[hashtndex)->key I=
//g0 to next cell
+hashIndex;
82Data Structures
‘/Iwrap around the table
hashIndex R= SIZES
hasharray[hashIndex] = item;
Delete Operation
Whenever an element is to be deleted, compute the hash code of the key passed and
locate the index using that hash code as an index in the array. Use linear probing to get
the element ahead if an element is not found at the computed hash code. When found,
store a dummy item there to keep the performance of the hash table intact.
struct Datatten* delete(struct Datatten* item){
Int key = item->key;
//get the hash
int hashIndex = hashCode(key) ;
//move in array until an empty
white(hasharray[hashindex] !=MULL){
LF (hasharray[hashIndex]->key == key)(
struct DataTtem* temp = hashArray[hashIndex];
I/assign a dunmy item at deleted position
hashArray[hashindex] = cummyltems
return temp;
}
11go to next cell
tthashIndex;
/Twrap around the table
hashindex = SIze;
}
return NULL;
83Data Structures
Hash Table Program in C
Hash Table is a data structure which stores data in an associative manner. In hash table,
the data is stored in an array format where each data value has its own unique index
value. Access of data becomes very fast, if we know the index of the desired data.
Implementation in C
Hinelude cetdio.h>
#include
Winclude
by
struct Datartem {
int data;
int keys
hb
struct Datalten* hasharray(SIZE];
struct DataItem* dunnyTtem;
struct Datalten” iten;
int hashCode(int key){
return key % SIZE5
struct Datalten “search(int key){
//get the hash
int hashtndex
shcode key) 5
J/move in array until an enpty
while(hashArray[hashIndex] I= NULL){
i#(hashdrray[hashindex]->key
return hashArray [hashindex];
key)
84Data Structures
//g0 to next cell
shashIndex;
{Jura around the table
hashIndex %= SIZE
return NULLS
void insert(int key,int data){
struct DataTtem titem = (struct Datertent) malloc(sizeof(struct
Daterten)); item-rdata = dete;
stem->key = key;
//get the hash
int hashtndex = hashcode(key);
[/move in array until an empty or deleted cell while (hashArray[hashindex]
MULL 8& hashAeray[hashIndex]-skey I= -1){
Hig to next cell
+thashIndex;
/Iwrap around the table
hashindex X= StZe;
hasharray[hashIndex] = item;
struct Datatten* delete(struct Datalten* item){
int key = iten=>key;
//get the hash
85Data Structures
int hashIndex = hashCode( key);
J/move in array until an empty
while(hasharray[hashindex] != NULL){
key){
struct Datattem* temp = hashArray[hashIndex];
if(hashArray [hashIndex]->key
//assign a dummy item et deleted position
hashArray[hashIndex] = dummyltem;
return temp;
Hgo to next cell
+hashindex;
/Iwrap around the table
hashIndex %= SIZE;
return NULLS
void display(){
int 2 = 95
for(i = 0; ieStZe; 44) (
Lf(hashanray[1] = NULL)
printf (" (%d,%d)", hasharray[i]->key,hasharray[i]->data);
else
printe(t a~
printf(*\n")3
86Data Structures
int main(){
dunmyrten = (struct Datalten) malloc(sizeof(struct,
Datattem)); durmyitem-rdata = -1;
dunmyTten=>key = -15
insert(1, 20);
insert(2, 78)
insert(42, 88);
insert(4, 25);
insert(12, 44)
insert(14, 32);
insert(27, 11);
insert (13, 78);
insert (37, 9795,
display);
Stem = search(37);
Ae(dtem t= NULL)E
printf("Elenent found: %d\n", iten-
odata); else {
print#("Element not found\n");
delete (item);
item = eearch(37);
Sf (item [= NULL){
printf("Elenent found: d\n"
ddata); else {
» item
printf("Element not found\s
25
87Data Structures
If we compile and run the above program, it will produce the following result —
m~ (4,28) (2,78) (42,80) (4,25) me me eee me (22,44)
(93,78) (44,32) ~~ ~~ (47,21) (37,97) ~~
Elenent found: 97
Elenant not found
88