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

DSA_Module 2

DSa

Uploaded by

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

DSA_Module 2

DSa

Uploaded by

MAAZ KHAN
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

~ASIF KHAN ~MAAZ KHAN

23EC29 23EC28
Data Structure & Algorithm
Module 2: Stack and Queues

➢ Stack Data Structure


Stack Data Structure is a linear data structure that follows LIFO (Last In First Out)
Principle , so the last element inserted is the first to be popped out. In this article, we will
cover all the basics of Stack, Operations on Stack, its implementation, advantages,
disadvantages which will help you solve all the problems based on Stack.

✓ What is Stack Data Structure?


Stack is a linear data structure based on LIFO(Last In First Out) principle in which the
insertion of a new element and removal of an existing element takes place at the same end
represented as the top of the stack.
To implement the stack, it is required to maintain the pointer to the top of the stack , which
is the last element to be inserted because we can access the elements only on the top of
the stack.
✓ LIFO(Last In First Out) Principle in Stack Data Structure:
This strategy states that the element that is inserted last will come out first. You can take a
pile of plates kept on top of each other as a real-life example. The plate which we put last is
on the top and since we remove the plate that is at the top, we can say that the plate that was
put last comes out first.
✓ Representation of Stack Data Structure:
Stack follows LIFO (Last In First Out) Principle so the element which is pushed last is popped
first.

✓ Types of Stack Data Structure:


• Fixed Size Stack : As the name suggests, a fixed size stack has a fixed size and cannot grow
or shrink dynamically. If the stack is full and an attempt is made to add an element to it, an
overflow error occurs. If the stack is empty and an attempt is made to remove an element
from it, an underflow error occurs.
• Dynamic Size Stack : A dynamic size stack can grow or shrink dynamically. When the stack
is full, it automatically increases its size to accommodate the new element, and when the
stack is empty, it decreases its size. This type of stack is implemented using a linked list, as it
allows for easy resizing of the stack.
✓ Basic Operations on Stack Data Structure:
In order to make manipulations in a stack, there are certain operations provided to us.
• push() to insert an element into the stack
• pop() to remove an element from the stack
• top() Returns the top element of the stack.
• isEmpty() returns true if stack is empty else false.
• isFull() returns true if the stack is full else false.
✓ Push Operation in Stack Data Structure:
Adds an item to the stack. If the stack is full, then it is said to be an Overflow condition.
Algorithm for Push Operation:
• Before pushing the element to the stack, we check if the stack is full .
• If the stack is full (top == capacity-1) , then Stack Overflows and we cannot insert the
element to the stack.
• Otherwise, we increment the value of top by 1 (top = top + 1) and the new value is inserted
at top position .
• The elements can be pushed into the stack till we reach the capacity of the stack.
✓ Pop Operation in Stack Data Structure:
Removes an item from the stack. The items are popped in the reversed order in which they
are pushed. If the stack is empty, then it is said to be an Underflow condition.
Algorithm for Pop Operation:
• Before popping the element from the stack, we check if the stack is empty .
• If the stack is empty (top == -1), then Stack Underflows and we cannot remove any element
from the stack.
• Otherwise, we store the value at top, decrement the value of top by 1 (top = top – 1) and
return the stored top value.
✓ Top or Peek Operation in Stack Data Structure:
Returns the top element of the stack.
Algorithm for Top Operation:
• Before returning the top element from the stack, we check if the stack is empty.
• If the stack is empty (top == -1), we simply print “Stack is empty”.
• Otherwise, we return the element stored at index = top .

✓ isEmpty Operation in Stack Data Structure:


Returns true if the stack is empty, else false.
Algorithm for isEmpty Operation:
• Check for the value of top in stack.
• If (top == -1) , then the stack is empty so return true .
• Otherwise, the stack is not empty so return false .
✓ isFull Operation in Stack Data Structure:
Returns true if the stack is full, else false.
Algorithm for isFull Operation:
• Check for the value of top in stack.
• If (top == capacity-1), then the stack is full so return true.
• Otherwise, the stack is not full so return false.
✓ Advantages of Stacks:
• Simplicity: Stacks are a simple and easy-to-understand data structure, making them
suitable for a wide range of applications.
• Efficiency: Push and pop operations on a stack can be performed in constant time
(O(1)), providing efficient access to data.
• Last-in, First-out (LIFO): Stacks follow the LIFO principle, ensuring that the last
element added to the stack is the first one removed. This behavior is useful in many
scenarios, such as function calls and expression evaluation.
• Limited memory usage: Stacks only need to store the elements that have been
pushed onto them, making them memory-efficient compared to other data
structures.

✓ Disadvantages of Stacks:
• Limited access: Elements in a stack can only be accessed from the top, making it
difficult to retrieve or modify elements in the middle of the stack.
• Potential for overflow: If more elements are pushed onto a stack than it can hold, an
overflow error will occur, resulting in a loss of data.
• Not suitable for random access: Stacks do not allow for random access to
elements, making them unsuitable for applications where elements need to be
accessed in a specific order.
• Limited capacity: Stacks have a fixed capacity, which can be a limitation if the
number of elements that need to be stored is unknown or highly variable.

➢ Infix to Postfix Algorithm


Scan the symbols of the expression from left to right and for each symbol,
do the following:
a. If symbol is an operand
• Print that symbol onto the screen.
b. If symbol is a left parenthesis
• Push it on the stack.
c. If symbol is a right parenthesis
• Pop all the operators from the stack upto the first left parenthesis and print them
on the screen.
• Discard the left and right parentheses.
d. If symbol is an operator
• If the precedence of the operators in the stack are greater than or equal to the
current operator, then
• Pop the operators out of the stack and print them onto the screen, and push the
current operator onto the stack.
• Else
Push the current operator onto the stack.
➢ Postfix to Infix Algorithm
Scan the symbols of the given postfix expression from left to right and for each
symbol, do the following:
1. If symbol is an operand
• Push it on the stack.
2. If symbol is an operator
• Pop two symbols out of the stack and apply the operator on these symbols.
• Push the result on the stack
3. After scanning all the symbols of the postfix expression, pop the remaining symbol
out of the stack and print it on the screen. The remaining symbol is the result obtained
after evaluating the postfix expression.

➢ Well Balanced Paranthesis Algorithm

1) Create an empty stack.


2) Scan the symbols of the expressions from left to right.
3) If the symbol is a left bracket, then push that symbol onto the stack.
4) If the symbol is a right bracket, do the following:
a) If the stack is empty
• Print "Invalid expression: Right brackets are more than the left brackets.
b) else
• Pop an element from the stack.
If the popped bracket does not match with right bracket
Print "Invalid expression: Mismatched brackets.
5) After scanning all the symbols of the expression
a) If stack is empty
• Print "Valid expression: brackets are well balanced."
b) else
• Print "Invalid expression: Left brackets are more than right brackets."
CODE
➢ Infix to Postfix
➢ #include <stdio.h>
➢ #include <stdlib.h>
➢ #include <string.h>
➢ #define MAX 100

➢ char stack[MAX];
➢ char infix[MAX],postfix[MAX];
➢ int top=-1;

➢ void push(char);
➢ char pop();
➢ int isEmpty();
➢ void infixtopostfix();
➢ int space(char);
➢ void print();
➢ int precedence (char);

➢ int isFull(){
➢ if(top==MAX-1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ int isEmpty(){
➢ if(top==-1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ void push(char data){

➢ if(isFull()){
➢ printf("Stack overflow");
➢ return;
➢ }
➢ top=top+1;
➢ stack[top]=data;
➢ }

➢ char pop(){

➢ if(isEmpty()){
➢ printf("Stack underflow");
➢ exit(1);
➢ }
➢ char valve;
➢ valve=stack[top];


➢ top=top-1;
➢ return valve;
➢ }

➢ int space(char c){
➢ if(c==' '||c=='\t')
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ void print(){

➢ int i=0;
➢ printf("The postfix expression is : ");
➢ while(postfix[i]){
➢ printf("%c",postfix[i++]);
➢ }
➢ printf("\n");
➢ }

➢ int precedence(char symbol){

➢ switch(symbol){

➢ case '^':
➢ return 3;

➢ case '*':
➢ case '/':
➢ return 2;

➢ case '+':
➢ case '-':
➢ return 1;

➢ default :
➢ return 0;
➢ }
➢ }

➢ void infixtopostfix(){

➢ int i,j=0;
➢ char symbol,next;

➢ for(i=0;i<strlen(infix);i++)
➢ {
➢ symbol=infix[i];

➢ if(!space(symbol))
➢ {


➢ switch(symbol)
➢ {
➢ case '(':
➢ push(symbol);
➢ break;

➢ case ')':
➢ while((next=pop())!='(')
➢ postfix[j++]=next;
➢ break;

➢ case '+':
➢ case '-':
➢ case '*':
➢ case '/':
➢ case '^':
➢ while(!isEmpty() && precedence(stack[top])>=precedence (symbol))
➢ {
➢ postfix[j++]=pop();
➢ }
➢ push(symbol);
➢ break;

➢ default :
➢ postfix[j++]=symbol;
➢ }
➢ }
➢ }



➢ while(!isEmpty()){
➢ postfix[j++]=pop();
➢ }
➢ postfix[j]='\0';

➢ }

➢ int main(){

➢ printf("Enter the infix expression");

➢ fgets(infix, MAX, stdin);
➢ // Remove the newline character if it exists
➢ infix[strcspn(infix, "\n")] = '\0';

➢ infixtopostfix();

➢ print();

➢ return 0;
➢ }
➢ Postfix Evaluation
➢ #include <stdio.h>
➢ #include <stdlib.h>
➢ #include <string.h>
➢ #include <math.h>
➢ #define MAX 100

➢ char stack[MAX];
➢ char infix[MAX],postfix[MAX];
➢ int top=-1;

➢ void push(char);
➢ char pop();
➢ int isEmpty();
➢ void infixtopostfix();
➢ int space(char);
➢ void print();
➢ int precedence (char);

➢ int isFull(){
➢ if(top==MAX-1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ int isEmpty(){
➢ if(top==-1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ void push(char data){

➢ if(isFull()){
➢ printf("Stack overflow");
➢ return;
➢ }
➢ top=top+1;
➢ stack[top]=data;
➢ }

➢ char pop(){

➢ if(isEmpty()){
➢ printf("Stack underflow");
➢ exit(1);
➢ }
➢ char valve;
➢ valve=stack[top];
➢ top=top-1;

➢ return valve;
➢ }

➢ int space(char c){
➢ if(c==' '||c=='\t')
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ void print(){

➢ int i=0;
➢ printf("The postfix expression is : ");
➢ while(postfix[i]){
➢ printf("%c",postfix[i++]);
➢ }
➢ printf("\n");
➢ }

➢ int precedence(char symbol){

➢ switch(symbol){

➢ case '^':
➢ return 3;

➢ case '*':
➢ case '/':
➢ return 2;

➢ case '+':
➢ case '-':
➢ return 1;

➢ default :
➢ return 0;
➢ }
➢ }

➢ void infixtopostfix(){

➢ int i,j=0;
➢ char symbol,next;

➢ for(i=0;i<strlen(infix);i++)
➢ {
➢ symbol=infix[i];

➢ if(!space(symbol))
➢ {



➢ switch(symbol)
➢ {
➢ case '(':
➢ push(symbol);
➢ break;

➢ case ')':
➢ while((next=pop())!='(')
➢ postfix[j++]=next;
➢ break;

➢ case '+':
➢ case '-':
➢ case '*':
➢ case '/':
➢ case '^':
➢ while(!isEmpty() && precedence(stack[top])>=precedence (symbol))
➢ {
➢ postfix[j++]=pop();
➢ }
➢ push(symbol);
➢ break;

➢ default :
➢ postfix[j++]=symbol;
➢ }
➢ }
➢ }

➢ while(!isEmpty()){
➢ postfix[j++]=pop();
➢ }
➢ postfix[j]='\0';

➢ }


➢ int postfix_evalve(){

➢ int i,a,b;

➢ for(i=0;i<strlen(postfix);i++){

➢ if(postfix[i]>='0' && postfix[i]<='9')
➢ push(postfix[i]-'0');

➢ else{

➢ a=pop();
➢ b=pop();

➢ switch(postfix[i]){


➢ case '+':
➢ push(b+a);
➢ break;

➢ case '-':
➢ push(b-a);
➢ break;

➢ case '*':
➢ push(b*a);
➢ break;

➢ case '/':
➢ push(b/a);
➢ break;

➢ case '^':
➢ push(pow(b,a));
➢ break;

➢ }

➢ }


➢ }
➢ return pop();
➢ }

➢ int main(){

➢ printf("Enter the infix expression :");

➢ fgets(infix, MAX, stdin);
➢ // Remove the newline character if it exists
➢ infix[strcspn(infix, "\n")] = '\0';

➢ infixtopostfix();

➢ print();

➢ int result ;

➢ result=postfix_evalve();

➢ printf("Result obtained after postfix evaluation is : %d", result);

➢ return 0;
➢ }

➢ Stack OverAll
➢ #include <stdio.h>
➢ #include <stdlib.h>
➢ #define MAX 4

➢ int stack[MAX];
➢ int top=-1;

➢ int isFull(){
➢ if(top==MAX-1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ int isEmpty(){
➢ if(top==-1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ void push(int data){

➢ if(isFull()){
➢ printf("Stack overflow");
➢ return;
➢ }
➢ top=top+1;
➢ stack[top]=data;
➢ }

➢ int pop(){

➢ if(isEmpty()){
➢ printf("Stack underflow");
➢ exit(1);
➢ }
➢ int valve;
➢ valve=stack[top];
➢ top=top-1;
➢ return valve;
➢ }

➢ int peek(){

➢ if(isEmpty()){
➢ printf("Stack underflow");
➢ exit(1);
➢ }
➢ return stack[top];
➢ }

➢ void print(){

➢ if(top==-1){
➢ printf("Stack underflow");
➢ return;
➢ }
➢ for(int i=top;i>=0;i--){
➢ printf("%d ",stack[i]);
➢ }
➢ }

➢ int main (){

➢ int choice,data;

➢ while(1){

➢ printf("\n");
➢ printf("1. Push\n");
➢ printf("2. Pop\n");
➢ printf("3. Print the topmost element\n");
➢ printf("4. Print All the elements\n");
➢ printf("5. Quit\n");

➢ printf("Enter your choice\n ");
➢ scanf("%d",&choice);

➢ switch(choice){

➢ case 1:
➢ printf("Enter element that want to push into stack :\n ");
➢ scanf("%d",&data);
➢ push(data);
➢ break;

➢ case 2:
➢ data=pop();
➢ printf("The deleted element is %d :\n ",data);
➢ break;

➢ case 3:
➢ printf("The topmost element is stack is %d :\n ",peek());
➢ break;

➢ case 4:
➢ print ();
➢ break;

➢ case 5:
➢ exit(1);
➢ break;

➢ default :
➢ printf("Invalid choice");
➢ break ;

➢ }
➢ }
➢ }
➢ Wellformed Paranthesis
➢ #include <stdio.h>
➢ #include <stdlib.h>
➢ #include <string.h>
➢ #define MAX 100

➢ char stack[MAX];
➢ int top = -1;

➢ void push(char);
➢ char pop();
➢ int isEmpty();
➢ int isFull();
➢ int parenthesis(char *);
➢ int match(char, char);

➢ int isFull() {
➢ if (top == MAX - 1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ int isEmpty() {
➢ if (top == -1)
➢ return 1;
➢ else
➢ return 0;
➢ }

➢ void push(char data) {
➢ if (isFull()) {
➢ printf("Stack overflow\n");
➢ return;
➢ }
➢ top = top + 1;
➢ stack[top] = data;
➢ }

➢ char pop() {
➢ if (isEmpty()) {
➢ printf("Stack underflow\n");
➢ exit(1);
➢ }
➢ char value;
➢ value = stack[top];
➢ top = top - 1;
➢ return value;
➢ }
➢ int match(char a, char b) {
➢ if (a == '(' && b == ')')
➢ return 1;
➢ if (a == '[' && b == ']')
➢ return 1;
➢ if (a == '{' && b == '}')
➢ return 1;

➢ return 0;
➢ }

➢ int parenthesis(char *s) {
➢ char temp;
➢ for (int i = 0; i < strlen(s); i++) {
➢ if (s[i] == '(' || s[i] == '[' || s[i] == '{') {
➢ push(s[i]);
➢ }
➢ if (s[i] == ')' || s[i] == ']' || s[i] == '}') {
➢ if (isEmpty()) {
➢ printf("Right brackets are more than left brackets\n");
➢ return 0;
➢ } else {
➢ temp = pop();
➢ if (!match(temp, s[i])) {
➢ printf("Mismatched brackets\n");
➢ return 0;
➢ }
➢ }
➢ }
➢ }

➢ if (isEmpty()) {
➢ printf("Brackets are well balanced\n");
➢ return 1;
➢ } else {
➢ printf("Left brackets are more than right brackets\n");
➢ return 0;
➢ }
➢ }

➢ int main() {
➢ char exp[MAX];

➢ printf("Enter the expression: ");
➢ fgets(exp, MAX, stdin);
➢ // Remove the newline character if it exists
➢ exp[strcspn(exp, "\n")] = '\0';

➢ int balance;

➢ balance = parenthesis(exp);
➢ if (balance == 1)
➢ printf("Expression is valid\n");
➢ else
➢ printf("Expression is not valid\n");

➢ return 0;
➢ }

Introduction to Queue Data Structure
Queue Data Structure is a linear data structure that follows FIFO (First In First Out)
Principle, so the first element inserted is the first to be popped out. In this article, we will
cover all the basics of Queue, Operations on Queue, its implementation, advantages,
disadvantages which will help you solve all the problems based on Queue.

What is Queue Data Structure?


Queue Data Structure is a linear data structure that is open at both ends and the operations
are performed in First In First Out (FIFO) order.
We define a queue to be a list in which all additions to the list are made at one end (back of
the queue), and all deletions from the list are made at the other end(front of the
queue). The element which is first pushed into the order, the delete operation is first
performed on that.

FIFO Principle of Queue Data Structure:


• A Queue is like a line waiting to purchase tickets, where the first person in line is the first
person served. (i.e. First Come First Serve).
• Position of the entry in a queue ready to be served, that is, the first entry that will be removed
from the queue, is called the front of the queue(sometimes, head of the queue). Similarly,
the position of the last entry in the queue, that is, the one most recently added, is called
the rear (or the tail) of the queue.
Representation of Queue Data Structure:
The image below shows how we represent Queue Data Structure:

Types of Queue Data Structure:


Queue data structure can be classified into 4 types:
There are different types of queues:
1. Simple Queue: Simple Queue simply follows FIFO Structure. We can only insert the element
at the back and remove the element from the front of the queue.
2. Double-Ended Queue (Dequeue): In a double-ended queue the insertion and deletion
operations, both can be performed from both ends. They are of two types:
• Input Restricted Queue: This is a simple queue. In this type of queue, the input can
be taken from only one end but deletion can be done from any of the ends.
• Output Restricted Queue: This is also a simple queue. In this type of queue, the
input can be taken from both ends but deletion can be done from only one end.
3. Circular Queue: This is a special type of queue where the last position is connected back to
the first position. Here also the operations are performed in FIFO order.
4. Priority Queue: A priority queue is a special queue where the elements are accessed based
on the priority assigned to them. They are of two types:
• Ascending Priority Queue: In Ascending Priority Queue, the elements are arranged in
increasing order of their priority values. Element with smallest priority value is
popped first.
• Descending Priority Queue: In Descending Priority Queue, the elements are
arranged in decreasing order of their priority values. Element with largest priority is
popped first.

Basic Operations in Queue Data Structure:


Some of the basic operations for Queue in Data Structure are:
1. Enqueue: Adds (or stores) an element to the end of the queue..
2. Dequeue: Removal of elements from the queue.
3. Peek or front: Acquires the data element available at the front node of the queue without
deleting it.
4. rear: This operation returns the element at the rear end without removing it.
5. isFull: Validates if the queue is full.
6. isEmpty: Checks if the queue is empty.
There are a few supporting operations (auxiliary operations):
1. Enqueue Operation in Queue Data Structure:
Enqueue() operation in Queue adds (or stores) an element to the end of the queue.
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, return overflow error and exit.
• Step 3: If the queue is not full, increment the rear pointer to point to the next empty space.
• Step 4: Add the data element to the queue location, where the rear is pointing.
• Step 5: return success.

2. Dequeue Operation in Queue Data Structure:


Removes (or access) the first element from the queue.
The following steps are taken to perform the dequeue operation:
• Step 1: Check if the queue is empty.
• Step 2: If the queue is empty, return the underflow error and exit.
• Step 3: If the queue is not empty, access the data where the front is pointing.
• Step 4: Increment the front pointer to point to the next available data element.
• Step 5: The Return success.
Advantages of Queue:
1) A large amount of data can be managed efficiently with ease.
2) Operations such as insertion and deletion can be performed with ease as it follows
the first in first out rule.
3) Queues are useful when a particular service is used by multiple consumers.
4) Queues are fast in speed for data inter- process communication.
5) Queues can be used in the implementation of other data structures.

Disadvantages of Queue:
1) The operations such as insertion and deletion of elements from the middle are time
consuming.
2) In a classical queue, a new element can only be inserted when the existing elements are
deleted from the queue.
3) Searching an element takes O(N) time.
4) Maximum size of a queue must be defined prior in case of array implementation.
CODE
➢ Queue Array
➢ a#include <stdio.h>
➢ #include <stdlib.h>
➢ #define MAX 8

➢ int queue[MAX];
➢ int front = -1;
➢ int rear = -1;

➢ int enqueue(int data) {
➢ if (rear == MAX - 1) {
➢ printf("Queue overflow\n");
➢ return -1;
➢ } else if (rear == -1 && front == -1) {
➢ rear = front = 0;
➢ queue[rear] = data;
➢ } else {
➢ rear++;
➢ queue[rear] = data;
➢ }

➢ return queue[rear];
➢ }

➢ int dequeue() {
➢ if (rear == -1 && front == -1) {
➢ printf("Queue underflow\n");
➢ return -1;
➢ } else if (rear == front) {
➢ int dequeued = queue[front];
➢ rear = front = -1; // Reset the queue
➢ return dequeued;
➢ } else {
➢ int dequeued = queue[front];
➢ front++;
➢ return dequeued;
➢ }
➢ }

➢ void print() {
➢ if (rear == -1 && front == -1) {
➢ printf("Queue is empty\n");
➢ } else {
➢ for (int i = front; i <= rear; i++) {
➢ printf("%d ", queue[i]);
➢ }
➢ printf("\n");
➢ }
➢ }
➢ int main() {
➢ printf("%d as a data entered in queue \n", enqueue(78));
➢ printf("%d as a data entered in queue \n", enqueue(35));
➢ printf("%d as a data entered in queue \n", enqueue(88));
➢ printf("%d as a data removed from queue \n", dequeue());

➢ print();

➢ return 0;
➢ }
➢ Circular Queue Array
➢ #include <stdio.h>
➢ #include <stdlib.h>
➢ #define MAX 8

➢ int queue[MAX];
➢ int front = -1;
➢ int rear = -1;

➢ void enqueue(int x) {
➢ if (front == -1 && rear == -1) {
➢ front = rear = 0;
➢ queue[rear] = x;
➢ }
➢ else if ((rear + 1) % MAX == front) {
➢ printf("Queue overflow\n");
➢ }
➢ else {
➢ rear = (rear + 1) % MAX;
➢ queue[rear] = x;
➢ }
➢ }

➢ void dequeue() {
➢ if (front == -1 && rear == -1) {
➢ printf("Queue underflow\n");
➢ }
➢ else if (front == rear) {
➢ printf("%d dequeued\n", queue[front]);
➢ front = rear = -1;
➢ }
➢ else {
➢ printf("%d dequeued\n", queue[front]);
➢ front = (front + 1) % MAX;
➢ }
➢ }

➢ void print() {
➢ if (front == -1 && rear == -1) {
➢ printf("Queue is empty\n");
➢ }
➢ else {
➢ int i = front;
➢ printf("Queue: ");
➢ while (i != rear) {
➢ printf("%d ", queue[i]);
➢ i = (i + 1) % MAX;
➢ }
➢ printf("%d\n", queue[rear]);
➢ }
➢ }
➢ int main() {
➢ enqueue(54);
➢ enqueue(77);
➢ enqueue(24);
➢ dequeue();
➢ print();

➢ return 0;
➢ }
➢ Queue Linkedlist
➢ #include <stdio.h>
➢ #include <stdlib.h>

➢ struct node {
➢ int data;
➢ struct node *link;
➢ };

➢ struct node *front = NULL;
➢ struct node *rear = NULL;

➢ void enqueue(int x) {
➢ struct node *temp = malloc(sizeof(struct node));
➢ temp->data = x;
➢ temp->link = NULL;

➢ if (front == NULL && rear == NULL) {
➢ front = rear = temp;
➢ } else {
➢ rear->link = temp;
➢ rear = temp;
➢ }
➢ }

➢ void dequeue() {
➢ if (front == NULL) {
➢ printf("Queue is empty\n");
➢ return;
➢ }

➢ struct node *temp = front;
➢ printf("Dequeued: %d\n", front->data);
➢ front = front->link;
➢ free(temp);

➢ if (front == NULL) {
➢ rear = NULL; // If front becomes NULL, rear should also be NULL
➢ }
➢ }

➢ void peek() {
➢ if (front == NULL) {
➢ printf("Queue is empty\n");
➢ } else {
➢ printf("Front element: %d\n", front->data);
➢ }
➢ }
➢ void print() {
➢ if (front == NULL) {
➢ printf("Queue is empty\n");
➢ return;
➢ }

➢ struct node *temp = front;
➢ printf("Queue elements: ");
➢ while (temp != NULL) {
➢ printf("%d ", temp->data);
➢ temp = temp->link;
➢ }
➢ printf("\n");
➢ }

➢ int main() {
➢ enqueue(40);
➢ enqueue(36);
➢ enqueue(80);
➢ enqueue(66);
➢ dequeue();
➢ peek();
➢ print();
➢ return 0;
➢ }

You might also like