1.
Explain the implementation Queue using array representation and advice the
operations
· Enqueue: Adds an element to the rear of the queue.
· Dequeue: Removes an element from the front of the queue.
· Front: Returns the front element of the queue without removing it.
· IsEmpty: Checks if the queue is empty.
· IsFull: Checks if the queue is full (when the array has reached its maximum
capacity).
· Size: Returns the number of elements in the queue.
#include <stdio.h>
#include <stdlib.h>
#define MAX 5 // Maximum size of the queue
// Queue structure
typedef struct Queue {
int arr[MAX]; // Array to store queue elements
int front; // Front pointer
int rear; // Rear pointer
} Queue;
// Initialize the queue
void initQueue(Queue* q) {
q->front = -1;
q->rear = -1;
}
// Check if the queue is empty
int isEmpty(Queue* q) {
return q->front == -1;
}
// Check if the queue is full
int isFull(Queue* q) {
return q->rear == MAX - 1;
}
// Enqueue operation (Add an element to the rear)
void enqueue(Queue* q, int value) {
if (isFull(q)) {
printf("Queue is full. Cannot enqueue %d\n", value);
return;
}
if (q->front == -1) {
q->front = 0; // First element in the queue
}
q->rear++;
q->arr[q->rear] = value;
printf("Enqueued: %d\n", value);
}
// Dequeue operation (Remove an element from the front)
int dequeue(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty. Cannot dequeue.\n");
return -1;
}
int dequeuedValue = q->arr[q->front];
if (q->front == q->rear) {
q->front = q->rear = -1; // Queue is empty after this operation
} else {
q->front++;
}
return dequeuedValue;
}
// Get the front element without removing it
int front(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty.\n");
return -1;
}
return q->arr[q->front];
}
// Get the size of the queue
int size(Queue* q) {
if (isEmpty(q)) {
return 0;
}
return q->rear - q->front + 1;
}
// Display all elements in the queue
void display(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty.\n");
return;
}
printf("Queue: ");
for (int i = q->front; i <= q->rear; i++) {
printf("%d ", q->arr[i]);
}
printf("\n");
}
int main() {
Queue q;
initQueue(&q); // Initialize the queue
enqueue(&q, 10); // Enqueue 10
enqueue(&q, 20); // Enqueue 20
enqueue(&q, 30); // Enqueue 30
enqueue(&q, 40); // Enqueue 40
enqueue(&q, 50); // Enqueue 50
enqueue(&q, 60); // Try to enqueue when the queue is full
display(&q); // Display the queue
printf("Dequeued: %d\n", dequeue(&q)); // Dequeue an element
display(&q); // Display the queue again
printf("Front element: %d\n", front(&q)); // Display the front element
printf("Queue size: %d\n", size(&q)); // Get the size of the queue
return 0;
}
Output:
Enqueued: 10
Enqueued: 20
Enqueued: 30
Enqueued: 40
Enqueued: 50
Queue is full. Cannot enqueue 60
Queue: 10 20 30 40 50
Dequeued: 10
Queue: 20 30 40 50
Front element: 20
Queue size: 4
2.what is atack ? write an algorithim push and pop operations and
trace with an example?
A stack is a linear data structure that follows the LIFO (Last In, First Out) principle.
This means the last element added to the stack is the first one to be removed. It is
often described as a "stack of plates" where you add plates to the top of the stack, and
you remove plates from the top as well.
Key Operations on Stack
· Push: Adds an element to the top of the stack.
· Pop: Removes the top element from the stack.
· Top/Peek: Returns the top element without removing it.
· IsEmpty: Checks if the stack is empty.
· Size: Returns the number of elements in the stack
#include <stdio.h>
#include <stdlib.h>
#define MAX 5 // Maximum size of the stack
// Stack structure
typedef struct Stack {
int arr[MAX]; // Array to store stack elements
int top; // Top pointer to track the top element of the stack
} Stack;
// Initialize the stack
void initStack(Stack* s) {
s->top = -1; // Stack is initially empty
// Check if the stack is full
int isFull(Stack* s) {
return s->top == MAX - 1;
// Check if the stack is empty
int isEmpty(Stack* s) {
return s->top == -1;
// Push operation (Add an element to the stack)
void push(Stack* s, int value) {
if (isFull(s)) {
printf("Stack overflow! Cannot push %d\n", value);
return;
s->top++; // Increment the top pointer
s->arr[s->top] = value; // Place the element on top
printf("Pushed: %d\n", value);
// Pop operation (Remove the top element from the stack)
int pop(Stack* s) {
if (isEmpty(s)) {
printf("Stack underflow! Cannot pop.\n");
return -1;
int poppedValue = s->arr[s->top];
s->top--; // Decrement the top pointer
return poppedValue;
}
// Top operation (Get the top element without removing it)
int top(Stack* s) {
if (isEmpty(s)) {
printf("Stack is empty.\n");
return -1;
return s->arr[s->top];
// Display the stack
void display(Stack* s) {
if (isEmpty(s)) {
printf("Stack is empty.\n");
return;
printf("Stack: ");
for (int i = 0; i <= s->top; i++) {
printf("%d ", s->arr[i]);
printf("\n");
int main() {
Stack s;
initStack(&s); // Initialize the stack
// Push some elements onto the stack
push(&s, 10);
push(&s, 20);
push(&s, 30);
push(&s, 40);
push(&s, 50);
push(&s, 60); // This should cause an overflow as the stack is full
// Display the stack
display(&s);
// Pop some elements from the stack
printf("Popped: %d\n", pop(&s));
printf("Popped: %d\n", pop(&s));
// Display the stack after popping elements
display(&s);
// Peek at the top element
printf("Top element: %d\n", top(&s));
return 0;
}
OutPut:Pushed: 10
Pushed: 20
Pushed: 30
Pushed: 40
Pushed: 50
Stack overflow! Cannot push 60
Stack: 10 20 30 40 50
Popped: 50
Popped: 40
Stack: 10 20 30
Top element: 30
3.What is double ended queue(dequee) with example program?
Double-Ended Queue (Deque)
A Double-Ended Queue (Deque, pronounced as "deck") is a linear data structure that
allows the insertion and deletion of elements from both ends (front and rear). This is
unlike a standard queue, which allows insertion at the rear and deletion from the front
only. A deque can be thought of as a more flexible queue, supporting the following
operations:
Insert Front: Adds an element to the front of the deque.
Insert Rear: Adds an element to the rear of the deque.
Delete Front: Removes an element from the front of the deque.
Delete Rear: Removes an element from the rear of the deque.
Get Front: Retrieves the element from the front without removing it.
Get Rear: Retrieves the element from the rear without removing it.
IsEmpty: Checks if the deque is empty.
IsFull: Checks if the deque is full (if a size limit is defined).
A deque can be implemented using a variety of structures, such as arrays or linked
lists. Below, we'll implement a deque using an array in C.
Operations on a Deque
· Insert Front: Add an element at the front.
· Insert Rear: Add an element at the rear.
· Delete Front: Remove the element from the front.
· Delete Rear: Remove the element from the rear.
· Get Front: Get the front element.
· Get Rear: Get the rear element.
· Is Empty: Check if the deque is empty.
· Is Full: Check if the deque is full (if the size is fixed).
#include <stdio.h>
#include <stdlib.h>
#define MAX 5 // Define maximum size of deque
// Deque structure
typedef struct Deque {
int arr[MAX]; // Array to store deque elements
int front; // Front pointer
int rear; // Rear pointer
} Deque;
// Function to initialize the deque
void initDeque(Deque* dq) {
dq->front = -1;
dq->rear = -1;
// Check if the deque is empty
int isEmpty(Deque* dq) {
return dq->front == -1;
// Check if the deque is full
int isFull(Deque* dq) {
return (dq->front == 0 && dq->rear == MAX - 1) || (dq->rear == dq->front - 1);
// Insert at front
void insertFront(Deque* dq, int value) {
if (isFull(dq)) {
printf("Deque overflow! Cannot insert %d at the front.\n", value);
return;
if (dq->front == -1) { // Deque is empty
dq->front = dq->rear = 0;
} else if (dq->front == 0) { // Wrap around
dq->front = MAX - 1;
} else {
dq->front--;
}
dq->arr[dq->front] = value;
printf("Inserted %d at the front.\n", value);
// Insert at rear
void insertRear(Deque* dq, int value) {
if (isFull(dq)) {
printf("Deque overflow! Cannot insert %d at the rear.\n", value);
return;
if (dq->rear == -1) { // Deque is empty
dq->front = dq->rear = 0;
} else if (dq->rear == MAX - 1) { // Wrap around
dq->rear = 0;
} else {
dq->rear++;
dq->arr[dq->rear] = value;
printf("Inserted %d at the rear.\n", value);
// Delete from front
int deleteFront(Deque* dq) {
if (isEmpty(dq)) {
printf("Deque underflow! Cannot delete from the front.\n");
return -1;
int deletedValue = dq->arr[dq->front];
if (dq->front == dq->rear) { // Only one element
dq->front = dq->rear = -1;
} else if (dq->front == MAX - 1) { // Wrap around
dq->front = 0;
} else {
dq->front++;
return deletedValue;
// Delete from rear
int deleteRear(Deque* dq) {
if (isEmpty(dq)) {
printf("Deque underflow! Cannot delete from the rear.\n");
return -1;
int deletedValue = dq->arr[dq->rear];
if (dq->front == dq->rear) { // Only one element
dq->front = dq->rear = -1;
} else if (dq->rear == 0) { // Wrap around
dq->rear = MAX - 1;
} else {
dq->rear--;
return deletedValue;
// Get the front element
int getFront(Deque* dq) {
if (isEmpty(dq)) {
printf("Deque is empty.\n");
return -1;
return dq->arr[dq->front];
// Get the rear element
int getRear(Deque* dq) {
if (isEmpty(dq)) {
printf("Deque is empty.\n");
return -1;
return dq->arr[dq->rear];
// Display the deque
void display(Deque* dq) {
if (isEmpty(dq)) {
printf("Deque is empty.\n");
return;
printf("Deque: ");
int i = dq->front;
while (i != dq->rear) {
printf("%d ", dq->arr[i]);
i = (i + 1) % MAX;
printf("%d\n", dq->arr[dq->rear]);
// Main function to test the deque operations
int main() {
Deque dq;
initDeque(&dq);
// Insert elements at the front and rear
insertRear(&dq, 10); // Insert 10 at rear
insertFront(&dq, 20); // Insert 20 at front
insertRear(&dq, 30); // Insert 30 at rear
insertFront(&dq, 40); // Insert 40 at front
insertRear(&dq, 50); // Insert 50 at rear
insertFront(&dq, 60); // Try inserting 60 at front (overflows after the 5th element)
// Display the deque
display(&dq);
// Perform deletions from both ends
printf("Deleted from front: %d\n", deleteFront(&dq)); // Delete from front
printf("Deleted from rear: %d\n", deleteRear(&dq)); // Delete from rear
// Display the deque again
display(&dq);
// Get the front and rear elements
printf("Front element: %d\n", getFront(&dq));
printf("Rear element: %d\n", getRear(&dq));
return 0;
OUTPUT:Inserted 10 at the rear.
Inserted 20 at the front.
Inserted 30 at the rear.
Inserted 40 at the front.
Inserted 50 at the rear.
Deque overflow! Cannot insert 60 at the front.
Deque: 40 20 10 30 50
Deleted from front: 40
Deleted from rear: 50
Deque: 20 10 30
Front element: 20
Rear element: 30
4.Explain infix to postfix conversion using stack give a suitable
example?
The infix notation is the most common mathematical expression format, where
operators are written between the operands (e.g., A + B). However, computers prefer
postfix notation (also called Reverse Polish Notation), where operators follow their
operands (e.g., A B +). Postfix notation eliminates the need for parentheses and
operator precedence rules, making it easier to evaluate using a stac
Steps to Convert Infix to Postfix
Create an empty stack for operators and an empty list (or output string) for
the postfix expression.
Read the infix expression from left to right, one symbol at a time
· f the symbol is an operand (e.g., A, B, 3, etc.), append it directly to the postfix
expression.
· If the symbol is an operator (e.g., +, -, *, /):
Pop all operators from the stack that have higher or equal precedence than the
current operator and append them to the postfix expression.
Push the current operator onto the stack.
· If the symbol is a left parenthesis (, push it onto the stack.
Operator Precedence
Highest Precedence: *, / (multiplication and division)
Lowest Precedence: +, - (addition and subtraction)
Parentheses () have the highest precedence and are used to group operations.
Example: Infix to Postfix Conversion
Let's convert the following infix expression into postfix:
A+B*C-D/E
Steps:
Start with A: it's an operand, so add it to the postfix expression: A.
Next, + is an operator. Push it to the stack.
Next, B: it's an operand, so add it to the postfix expression: A B.
Next, * is an operator. It has higher precedence than +, so push it to the stack.
Next, C: it's an operand, so add it to the postfix expression: A B C.
Next, - is an operator. Pop * (which has higher precedence than -) from the
stack and add it to the postfix expression. Then, push - onto the stack.
Next, D: it's an operand, so add it to the postfix expression: A B C * D.
Next, / is an operator. It has higher precedence than -, so push it to the stack.
Next, E: it's an operand, so add it to the postfix expression: A B C * D E.
Now, the expression is finished. Pop all remaining operators from the stack
and add them to the postfix expression: A B C * + D E / -.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 100
// Stack structure
typedef struct Stack {
char arr[MAX];
int top;
} Stack;
// Function to initialize the stack
void initStack(Stack* s) {
s->top = -1;
// Function to check if the stack is empty
int isEmpty(Stack* s) {
return s->top == -1;
// Function to check if the stack is full
int isFull(Stack* s) {
return s->top == MAX - 1;
// Function to push an element onto the stack
void push(Stack* s, char value) {
if (isFull(s)) {
printf("Stack overflow!\n");
return;
}
s->arr[++(s->top)] = value;
// Function to pop an element from the stack
char pop(Stack* s) {
if (isEmpty(s)) {
return -1; // Stack is empty
return s->arr[s->top--];
// Function to get the top element of the stack without popping it
char peek(Stack* s) {
if (isEmpty(s)) {
return -1; // Stack is empty
return s->arr[s->top];
// Function to check if a character is an operator
int isOperator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/');
}
// Function to get the precedence of operators
int precedence(char c) {
if (c == '*' || c == '/') {
return 2;
} else if (c == '+' || c == '-') {
return 1;
} else {
return 0;
// Function to convert infix to postfix
void infixToPostfix(char* infix, char* postfix) {
Stack s;
initStack(&s); // Initialize the stack
int j = 0; // Index for postfix
for (int i = 0; infix[i] != '\0'; i++) {
char ch = infix[i];
if (isalnum(ch)) { // If it's an operand (alphabet or digit), add to postfix
postfix[j++] = ch;
} else if (ch == '(') { // If it's a '(', push it to the stack
push(&s, ch);
} else if (ch == ')') { // If it's a ')', pop from the stack until '(' is encountered
while (!isEmpty(&s) && peek(&s) != '(') {
postfix[j++] = pop(&s);
pop(&s); // Pop '('
} else if (isOperator(ch)) { // If it's an operator
while (!isEmpty(&s) && precedence(peek(&s)) >= precedence(ch)) {
postfix[j++] = pop(&s);
push(&s, ch);
// Pop all remaining operators from the stack
while (!isEmpty(&s)) {
postfix[j++] = pop(&s);
postfix[j] = '\0'; // Null-terminate the postfix expression
// Main function to test the conversion
int main() {
char infix[MAX], postfix[MAX];
printf("Enter an infix expression: ");
fgets(infix, MAX, stdin);
// Remove newline character if present
int len = 0;
while (infix[len] != '\0') {
len++;
if (infix[len - 1] == '\n') {
infix[len - 1] = '\0';
infixToPostfix(infix, postfix); // Convert to postfix
printf("Postfix expression: %s\n", postfix);
return 0;
Input:Enter an infix expression: A + B * C - D / E
OutPut:Postfix expression: ABC*+DE/-
Write a program to implement Queue using a linked lists?
#include <stdio.h>
#include <stdlib.h>
// Node structure for the queue
typedef struct Node {
int data;
struct Node* next;
} Node;
// Queue structure
typedef struct Queue {
Node* front; // Front pointer
Node* rear; // Rear pointer
} Queue;
// Function to initialize the queue
void initQueue(Queue* q) {
q->front = q->rear = NULL;
// Function to check if the queue is empty
int isEmpty(Queue* q) {
return q->front == NULL;
// Function to enqueue (insert) an element at the rear
void enqueue(Queue* q, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed!\n");
return;
}
newNode->data = value;
newNode->next = NULL;
if (isEmpty(q)) {
q->front = q->rear = newNode; // If the queue is empty, both front and rear point
to the new node
} else {
q->rear->next = newNode; // Otherwise, add the new node at the rear
q->rear = newNode; // Update the rear pointer
printf("%d enqueued to the queue\n", value);
// Function to dequeue (remove) an element from the front
int dequeue(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty! Cannot dequeue.\n");
return -1; // Return -1 to indicate an error
Node* temp = q->front;
int dequeuedValue = temp->data;
q->front = q->front->next;
if (q->front == NULL) {
q->rear = NULL; // If the queue becomes empty, reset the rear pointer
free(temp); // Free the memory of the dequeued node
return dequeuedValue;
// Function to get the front element of the queue
int peek(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty!\n");
return -1; // Return -1 to indicate the queue is empty
return q->front->data;
// Function to display the elements of the queue
void displayQueue(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty!\n");
return;
Node* temp = q->front;
printf("Queue: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
printf("\n");
// Main function to test the queue operations
int main() {
Queue q;
initQueue(&q); // Initialize the queue
enqueue(&q, 10);
enqueue(&q, 20);
enqueue(&q, 30);
enqueue(&q, 40);
displayQueue(&q);
printf("Dequeued: %d\n", dequeue(&q));
printf("Dequeued: %d\n", dequeue(&q));
displayQueue(&q);
printf("Front element: %d\n", peek(&q));
enqueue(&q, 50);
enqueue(&q, 60);
displayQueue(&q);
return 0;
OutPUT:10 enqueued to the queue
20 enqueued to the queue
30 enqueued to the queue
40 enqueued to the queue
Queue: 10 20 30 40
Dequeued: 10
Dequeued: 20
Queue: 30 40
Front element: 30
50 enqueued to the queue
60 enqueued to the queue
Queue: 30 40 50 60