Data Structures Lab

Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

DATA STRUCTURES LAB

List of Experiments:
Exercise 1: Array Manipulation
i) Write a program to reverse an array.
ii) C Programs to implement the Searching Techniques – Linear & Binary Search
iii) C Programs to implement Sorting Techniques – Bubble, Selection and Insertion Sort
Exercise 2: Linked List Implementation
i) Implement a singly linked list and perform insertion and deletion operations.
ii) Develop a program to reverse a linked list iteratively and recursively.
iii) Solve problems involving linked list traversal and manipulation.
Exercise 3: Linked List Applications
i) Create a program to detect and remove duplicates from a linked list.
ii) Implement a linked list to represent polynomials and perform addition.
iii) Implement a double-ended queue (deque) with essential operations.
Exercise 4: Double Linked List Implementation
i) Implement a doubly linked list and perform various operations to understand its
properties and applications.
ii) Implement a circular linked list and perform insertion, deletion, and traversal
Exercise 5: Stack Operations
i) Implement a stack using arrays and linked lists.
ii) Write a program to evaluate a postfix expression using a stack.
iii) Implement a program to check for balanced parentheses using a stack.
Exercise 6: Queue Operations
i) Implement a queue using arrays and linked lists.
ii) Develop a program to simulate a simple printer queue system.
iii) Solve problems involving circular queues.
Exercise 7: Stack and Queue Applications
i) Use a stack to evaluate an infix expression and convert it to postfix.
ii) Create a program to determine whether a given string is a palindrome or not.
iii) Implement a stack or queue to perform comparison and check for symmetry.
Exercise 8: Binary Search Tree
i) Implementing a BST using Linked List.
ii) Traversing of BST.
Exercise 9: Hashing i) Implement a hash table with collision resolution techniques. ii) Write a program to implement
a simple cache using hashing.
Exercise 1: Array Manipulation
i) Write a program to reverse an array.

#include <stdio.h>

void readArray(int *a,int n)


{
int i;
printf("enter %d number of elements:",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
}

void writeArray(int *a,int n)


{
int i;
printf("the given array is:");
for(i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
}

void reverseArray(int *a,int n)


{
int l,r,temp;
l=0;
r=n-1;
while(l!=r)
{
temp=a[l];
a[l]=a[r];
a[r]=temp;
l++;
r--;
}
}

int main()
{
int a[100];
int n;
printf("enter size of the array:");
scanf("%d",&n);
readArray(a,n);
reverseArray(a,n);
writeArray(a,n);
return 0;
}
Exercise 1: Array Manipulation
ii) C Programs to implement the Searching Techniques – Linear & Binary Search
A) Linear Search
#include<stdio.h>
void readArray(int *a,int n)
{
int i;
printf("enter %d number of elements:\n");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
}

int linearSearch(int *a,int n,int key)


{
int found=0,loc=0;
int i;
for(i=0;i<n;i++)
{
if(a[i]==key)
{
found=1;
loc=i+1;
break;
}
}
return(loc);
}

int main()
{
int a[1000],n,key,loc;
printf("enter array size:");
scanf("%d",&key);
readArray(a,n);
printf("enter key:");
scanf("%d",&key);
loc=linearSearch(a,n,key);
if(loc)
{
printf("element found at loc=%d\n",loc);
}
else
{
printf("element not found:\n");
}
return 0;
}
B) Binary Search
#include<stdio.h>

void readArray(int * a, int n)


{
int i;
printf("Enter %d no. of elements:\n");
for (i = 0; i < n; i++)
{
scanf("%d", & a[i]);
}
}

int binarySearch(int * a, int n, int key)


{
int L = 0, loc = 0, mid;
int U = n - 1, found = 0;
while (L < U)
{
mid = (L + U) / 2;
if (a[mid] == key)
{
found = 1;
loc = (mid + 1);
break;
}
if (key > a[mid])
L = mid + 1;
else if (key < a[mid])
U = mid - 1;
}
return loc;
}

int main()
{
int a[1000], n, key, loc;
printf("Enter Array Size:");
scanf("%d", & n);
readArray(a, n);
printf("Enter key:");
scanf("%d", & key);
loc = binarySearch(a, n, key);
if (loc)
{
printf("Element found at loc=%d\n", loc);
}
else
{
printf("Element not found:\n");
}
return 0;
}
Exercise 1: Array Manipulation
iii) C Programs to implement Sorting Techniques – Bubble, Selection and Insertion Sort
A) Bubble
#include <stdio.h>

void readArray(int *a,int n)


{
int i;
printf("enter %d number of elements:",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
}

void writeArray(int *a,int n)


{
int i;
printf("the given array is:");
for(i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
}

void bubbleSort(int *a,int n)


{
int i,j,temp;
for(i=0;i<(n-2);i++)
{
for(j=i+1;j<=(n-1);j++)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}

int main()
{
int a[100];
int n;
printf("enter size of the array:");
scanf("%d",&n);
readArray(a,n);
bubbleSort(a,n);
writeArray(a,n);
return 0;
}
B) Selection
#include<stdio.h>

void readArray(int *a,int n)


{
int i;
printf("enter %d number of elements:",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
}

void writeArray(int *a,int n)


{
int i;
printf("the given array is:");
for(i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
}

void selectionSort(int *a, int n)


{
int i, j, small, temp;
for (i = 0; i < n-1; i++)
{
small = i;
for (j = i+1; j < n; j++)
{
if (a[j] < a[small])
small = j;
}
temp = a[small];
a[small] = a[i];
a[i] = temp;
}
}

int main()
{
int a[100];
int n;
printf("enter size of the array:");
scanf("%d",&n);
readArray(a,n);
selectionSort(a,n);
writeArray(a,n);
return 0;
}
C) Insertion Sort
#include<stdio.h>
void readArray(int *a,int n)
{
int i;
printf("enter %d number of elements:",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
}
void writeArray(int *a,int n)
{
int i;
printf("the given array is:");
for(i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
}
void insertionSort(int *a,int n)
{
int i,j,x,r;
for(i=1;i<=(n-1);i++)
{
x=a[i];
r=i;
while(r!=0 && x<a[r-1])
{
a[r]=a[r-1];
r=r-1;

}
a[r]=x;
}

int main()
{
int a[100];
int n;
printf("enter size of the array:");
scanf("%d",&n);
readArray(a,n);
insertionSort(a,n);
writeArray(a,n);
return 0;
}
Exercise 2: Linked List Implementation
i) Implement a singly linked list and perform insertion and deletion operations.
#include<stdio.h>
#include<stdlib.h>

typedef struct node


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

node* sllCreation(node *head)


{
int x;
node *p,*new;
while(1)
{
printf("Enter Node Element:");
scanf("%d",&x);
if(x==0) break;
new=(node*)malloc(sizeof(node));
new->data=x;
new->link=NULL;
if(head==NULL)
{
head=p=new;
}
else
{
p->link=new;
p=new;
}

}
return(head);
}

void sllInsertion(node *head, int x, int key)


{
node *p,*prev,*new;
p=head;
while(p!=NULL && p->data!=key)
{
prev=p;
p=p->link;
}
if(p==NULL)
{
printf("Key node not Found. Insetion not Possible.\n");
return;
}
new=(node*)malloc(sizeof(node));
new->data=x;
new->link=NULL;
prev->link=new;
new->link=p;
}
void sllDeletion(node *head, int key)
{
node *p,*prev,*next;
p=head;
while(p!=NULL && p->data!=key)
{
prev=p;
p=p->link;
}
if(p==NULL)
{
printf("Key node not Found. Deletion not Possible.\n");
return;
}
next=p->link;
prev->link=next;
free(p);
}

void sllTraversal(node *head)


{
node *p;
p=head;
while(p!=NULL)
{
printf("%d->",p->data);
p=p->link;
}
printf("NULL.\n");

}
int main()
{
int ch,x,key;
node *head=NULL;
head=sllCreation(head);
while(1)
{
printf("\n........SLL Menu.......\n\n");
printf("Insertion...........1\n");
printf("Deletion............2\n");
printf("Traversal...........3\n");
printf("Exit................4\n");

printf("\nEnter Your Choice(1-4):");


scanf("%d",&ch);

switch(ch)
{
default: printf("Ivalid Choice. Try again.\n");
break;
case 1: printf("Enter Node Element:");
scanf("%d",&x);
printf("Enter Key Element:");
scanf("%d",&key);
sllInsertion(head,x,key);
break;
case 2: printf("Enter Key Element:");
scanf("%d",&key);
sllDeletion(head,key);
break;
case 3: sllTraversal(head);
break;
case 4: exit(0);
}
}
return 0;
}
Exercise 2: Linked List Implementation
ii) Develop a program to reverse a linked list
#include <stdio.h>
#include <stdlib.h>

typedef struct node {


int data;
struct node *link;
} node;

node* sllCreation(node *head)


{
int x;
node *p, *new;
while(1)
{
printf("Enter Node Element(0 to Exit): ");
scanf("%d", &x);
if(x == 0) break;
new = (node*)malloc(sizeof(node));
new->data = x;
new->link = NULL;
if(head == NULL)
{
head = p = new;
}
else
{
p->link = new;
p = new;
}
}
return head;
}

void sllTraverse(node* head)


{
node *p;
p = head;
while (p != NULL)
{
printf("%d -> ", p->data);
p = p->link;
}
printf("NULL\n");
}

node* sllReverse(node* head)


{
node *prev = NULL, *current = head, *next = NULL;

while (current != NULL)


{
next = current->link;
current->link = prev;
prev = current;
current = next;
}
head = prev;

return head;
}

int main()
{
node *head = NULL;
printf("Enter elements for the linked list:\n");
head = sllCreation(head);
printf("\nOriginal linked list:\n");
sllTraverse(head);

head = sllReverse(head);

printf("\nReversed linked list:\n");


sllTraverse(head);

return 0;
}
Exercise 3: Linked List Applications
i) Create a program to detect and remove duplicates from a linked list.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node* link;
}node;
node* sllCreation(node *head)
{
int x;
node *p,*new;
while(1)
{
printf("Enter Node Element:");
scanf("%d",&x);
if(x==0) break;
new=(node*)malloc(sizeof(node));
new->data=x;
new->link=NULL;
if(head==NULL)
{
head=p=new;
}
else
{
p->link=new;
p=new;
}

}
return(head);
}
void removeDuplicates(node *head)
{
if (head == NULL) return;

node *current = head, *ptr1, *duplicate;


while (current != NULL && current->link != NULL)
{
ptr1 = current;
while (ptr1->link != NULL)
{
if (current->data == ptr1->link->data)
{
duplicate = ptr1->link;
ptr1->link = ptr1->link->link;
free(duplicate);
}
else
{
ptr1 = ptr1->link;
}
}
current = current->link;
}
}
void sllTraverse(node* head)
{
node *p;
p=head;
while (p!= NULL)
{
printf("%d -> ", p->data);
p = p->link;
}
printf("NULL\n");
}

int main()
{
node *head = NULL;
head=sllCreation(head);
removeDuplicates(head);
printf("\nReversed linked list\n");
sllTraverse(head);
return 0;
}
Exercise 3: Linked List Applications
ii) Implement a linked list to represent polynomials and perform addition.
#include<stdio.h>
#include<stdlib.h>
typedef struct polynode
{
int coef;
int exp;
struct polynode *link;
}polynode;

polynode* polyCreation(polynode *p)


{
int c,e,d,i,x;
polynode *new,*l;
printf("Enter Max Degree:");
scanf("%d",&d);
for(i=d;i>=0;i--)
{
printf("Enter Details of Degree:%d\n",i);
printf("Enter x value(0 to remove,non zero to add):");
scanf("%d",&x);
if(x!=0)
{
printf("Enter Coefficient:");
scanf("%d",&c);
new=(polynode*)malloc(sizeof(polynode));
new->coef=c;
new->exp=i;
new->link=NULL;
if(p==NULL)
{
p=new;
l=p;
}
else
{
l->link=new;
l=new;
}
}
}
return(p);
}

void polyDisplay(polynode *p)


{
polynode *pt;
pt=p;
printf("\nThe Polynomial Equation:");
while(pt!=NULL)
{
printf("+%dx^%d",pt->coef,pt->exp);
pt=pt->link;
}
}
polynode* polyAddition(polynode *p1,polynode *p2)
{
polynode *p1p,*p2p,*p=NULL,*pt,*new;
int coef;
p1p=p1;
p2p=p2;
while(p1p!=NULL && p2p!=NULL)
{
new=(polynode*)malloc(sizeof(polynode));
new->link=NULL;
if(p1p->exp==p2p->exp)
{
coef=p1p->coef+p2p->coef;
new->coef=coef;
new->exp=p1p->exp;
p1p=p1p->link;
p2p=p2p->link;
}
else if(p1p->exp>p2p->exp)
{
coef=p1p->coef;
new->coef=coef;
new->exp=p1p->exp;
p1p=p1p->link;
}
else
{
coef=p2p->coef;
new->coef=coef;
new->exp=p2p->exp;
p2p=p2p->link;
}
if(p==NULL)
{
p=new;
pt=p;
}
else
{
pt->link=new;
pt=new;
}
}
while(p1p!=NULL)
{
new=(polynode*)malloc(sizeof(polynode));
new->coef=p1p->coef;
new->exp=p1p->exp;
pt->link=new;
pt=new;
p1p=p1p->link;
}
while(p2p!=NULL)
{
new=(polynode*)malloc(sizeof(polynode));
new->coef=p2p->coef;
new->exp=p2p->exp;
pt->link=new;
pt=new;
p2p=p2p->link;
}
return(p);
}

int main()
{
polynode *p1=NULL,*p2,*p;
p1=polyCreation(NULL);
p2=polyCreation(NULL);
printf("\nFirst Polynomial:");
polyDisplay(p1);
printf("\nSecond Polynomial:");
polyDisplay(p2);
p=polyAddition(p1,p2);
printf("\nAddition of Two Polynomials:");
polyDisplay(p);
return 0;
}
Exercise 3: Linked List Applications
iii) Implement a double-ended queue (deque) with essential operations.
#include <stdio.h>
#include <stdlib.h>

typedef struct node


{
struct node *left;
int data;
struct node *right;
} node;

node *front = NULL;


node *rear = NULL;

void insertFront(int data)


{
node* new = (node*)malloc(sizeof(node));
new->data = data;
new->left = NULL;
new->right = front;

if (front == NULL)
{
front = new;
rear = new;
}
else
{
front->left = new;
front = new;
}
}

void insertRear(int data)


{
node* new = (node*)malloc(sizeof(node));
new->data = data;
new->right = NULL;
new->left = rear;

if (rear == NULL)
{
front = new;
rear = new;
}
else
{
rear->right = new;
rear = new;
}
}
void deleteFront()
{
if (front == NULL)
{
printf("Deque is empty, cannot delete from front.\n");
return;
}
node* temp = front;
front = front->right;
if (front != NULL)
{
front->left = NULL;
}
else
{
rear = NULL;
}
free(temp);
}

void deleteRear()
{
if (rear == NULL)
{
printf("Deque is empty, cannot delete from rear.\n");
return;
}
node* temp = rear;
rear = rear->left;
if (rear != NULL)
{
rear->right = NULL;
}
else
{
front = NULL;
}
free(temp);
}

void displayDeque()
{
if (front == NULL)
{
printf("Deque is empty.\n");
return;
}
node* p = front;
while (p != NULL)
{
printf("%d -> ", p->data);
p = p->right;
}
printf("NULL\n");
}
int main()
{
int ch,x;
while(1)
{
printf("\n......Double Ended Queue Menu......\n");
printf("Insert at Front........1\n");
printf("Insert at Rear.........2\n");
printf("Delete at Front........3\n");
printf("Delete at Rear.........4\n");
printf("DQ Display.............5\n");
printf("Exit...................6\n");
printf("Enter Your Choice(1-6):");
scanf("%d",&ch);
switch(ch)
{
default: printf("Invalid Choice, Try Again.\n");
break;
case 1: printf("Enter DQueue Element:");
scanf("%d",&x);
insertFront(x);
break;
case 2: printf("Enter DQueue Element:");
scanf("%d",&x);
insertRear(x);
break;
case 3: deleteFront();
break;
case 4: deleteRear();
break;
case 5: displayDeque();
break;

case 6: exit(0);
}
}
}
Exercise 4: Double Linked List Implementation
i) Implement a doubly linked list and perform various operations to understand its properties and applications.
#include<stdio.h>
#include<stdlib.h>

typedef struct node


{
struct node *left;
int data;
struct node *right;
}node;

node* dllCreation(node *head)


{
int x;
node *p,*new;
while(1)
{
printf("Enter Node Element:");
scanf("%d",&x);
if(x==0) break;
new=(node*)malloc(sizeof(node));
new->data=x;
new->left=new->right=NULL;
if(head==NULL)
{
head=p=new;
}
else
{
p->right=new;
new->left=p;
p=new;
}

}
return(head);
}

void dllInsertion(node *head, int x, int key)


{
node *p,*prev,*new;
p=head;
while(p!=NULL && p->data!=key)
{
p=p->right;
}
if(p==NULL)
{
printf("Key node not Found. Insetion not Possible.\n");
return;
}
new=(node*)malloc(sizeof(node));
new->data=x;
new->left=new->right=NULL;
prev=p->left;
prev->right=new;
new->left=prev;
new->right=p;
p->left=new;
}

void dllDeletion(node *head, int key)


{
node *p,*prev,*next;
p=head;
while(p!=NULL && p->data!=key)
{
p=p->link;
}
if(p==NULL)
{
printf("Key node not Found. Deletion not Possible.\n");
return;
}
next=p->link;
prev->link=next;
free(p);
}

void dllTraversal(node *head)


{
node *p;
p=head;
while(p!=NULL)
{
printf("%d->",p->data);
p=p->link;
}
printf("NULL.\n");

int main()
{
int ch,x,key;
node *head=NULL;
head=dllCreation(head);
while(1)
{
printf("\n........dll Menu.......\n\n");
printf("Insertion...........1\n");
printf("Deletion............2\n");
printf("Traversal...........3\n");
printf("Exit................4\n");

printf("\nEnter Your Choice(1-4):");


scanf("%d",&ch);

switch(ch)
{
default: printf("Ivalid Choice. Try again.\n");
break;
case 1: printf("Enter Node Element:");
scanf("%d",&x);
printf("Enter Key Element:");
scanf("%d",&key);
dllInsertion(head,x,key);
break;
case 2: printf("Enter Key Element:");
scanf("%d",&key);
dllDeletion(head,key);
break;
case 3: dllTraversal(head);
break;
case 4: exit(0);
}
}
return 0;
}
Exercise 4: Double Linked List Implementation
ii) Implement a circular linked list and perform insertion, deletion, and traversal
#include <stdio.h>
#include <stdlib.h>

typedef struct node


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

void insert(node **head, int x)


{
node *new = (node*)malloc(sizeof(node));
node *last = *head;
new->data = x;
new->link = *head;

if (*head == NULL)
{
new->link = new;
*head = new;
}
else
{
while (last->link != *head)
{
last = last->link;
}
last->link = new;
new->link = *head;
}

printf("Node inserted successfully.\n");


}

void delete(node **head, int key)


{
if (*head == NULL)
{
printf("List is empty.\n");
return;
}

node *p = *head, *previous = NULL;

if (p->data == key)
{
while (p->link != *head)
{
p = p->link;
}
if (*head == (*head)->link)
{
free(*head);
*head = NULL;
}
else
{
p->link = (*head)->link;
free(*head);
*head = p->link;
}
printf("Node deleted successfully.\n");
return;
}

previous = *head;
while (p->link != *head && p->data != key)
{
previous = p;
p = p->link;
}

if (p->data == key)
{
previous->link = p->link;
free(p);
printf("Node deleted successfully.\n");
}
else
{
printf("Node with data %d not found.\n", key);
}
}

void traverse(node *head)


{
if (head == NULL)
{
printf("List is empty.\n");
return;
}

node *p = head;
printf("Circular Single Linked List: ");
do
{
printf("%d -> ", p->data);
p = p->link;
} while (p != head);
printf("HEAD\n");
}

int main()
{
node *head = NULL;
int ch, x, key;

while (1)
{
printf("\nCircular Single Linked List Menu\n");
printf("Insert..............1\n");
printf("Delete..............2\n");
printf("Traverse............3\n");
printf("Exit................4\n");
printf("Enter your choice: ");
scanf("%d", &ch);

switch (ch)
{
case 1:
printf("Enter the data to insert: ");
scanf("%d", &x);
insert(&head, x);
break;
case 2:
printf("Enter the data to delete: ");
scanf("%d", &key);
delete(&head, key);
break;
case 3:
traverse(head);
break;
case 4:
printf("Exiting program.\n");
exit(0);
break;
default:
printf("Invalid choice. Please try again.\n");
}
}
return 0;
}
Exercise 5: Stack Operations
i) Implement a stack using arrays and linked lists.
A) Stack using Arrays
#include<stdio.h>
#include<stdlib.h>
#define MAX 5
void push(int *stack, int *top,int x)
{
if(*top>=(MAX)-1)
{
printf("Stack Overflow.\n");
return;
}
printf("top=%d\n",*top);
*top=*top+1;
printf("top=%d\n",*top);
stack[*top]=x;
}

int pop(int *stack,int *top)


{
int x,i;
if(*top<0)
{
printf("Stack Underflow.\n");
return -1;
}
x=stack[*top];
*top=*top-1;
return x;
}

void display(int *stack,int top)


{
int i;
if(top<0)
{
printf("Stack Underflow.\n");
return;
}
for(i=top;i>=0;i--)
{
printf("%d\n",stack[i]);
}
}

int main()
{
int ch;
int x,top=-1;
int stack[10];
while(1)
{
printf("\n......Stack Menu......\n");
printf("Push........1\n");
printf("Pop.........2\n");
printf("Display.....3\n");
printf("Exit........4\n");
printf("Enter Your Choice(1-4):");
scanf("%d",&ch);
switch(ch)
{
default: printf("Invalid Choice, Try Again.\n");
break;
case 1: printf("Enter Stack Element:");
scanf("%d",&x);
push(stack,&top,x);
break;
case 2: x=pop(stack,&top);
if(x!=-1)
{
printf("Poped Element=%d\n",x);
}
break;
case 3: display(stack,top);
break;

case 4:exit(0);
}
}
}

B) Stack using Linked List


#include <stdio.h>
#include <stdlib.h>

typedef struct node


{
int data;
struct node* next;
} node;

void push(node** top, int x)


{
node* new_node = (node*)malloc(sizeof(node));
if (!new_node)
{
printf("Stack Overflow.\n");
return;
}
new_node->data = x;
new_node->next = *top;
*top = new_node;
}

int pop(node** top)


{
if (*top == NULL)
{
printf("Stack Underflow.\n");
return -1;
}
node* temp = *top;
int popped = temp->data;
*top = (*top)->next;
free(temp);
return popped;
}

void display(node* top)


{
if (top == NULL)
{
printf("Stack is empty.\n");
return;
}
node* temp = top;
while (temp != NULL)
{
printf("%d\n", temp->data);
temp = temp->next;
}
}

int main()
{
int ch;
int x;
node* top = NULL;

while (1)
{
printf("\n......Stack Menu......\n");
printf("Push........1\n");
printf("Pop.........2\n");
printf("Display.....3\n");
printf("Exit........4\n");
printf("Enter Your Choice(1-4): ");
scanf("%d", &ch);

switch (ch)
{
case 1:
printf("Enter Stack Element: ");
scanf("%d", &x);
push(&top, x);
break;
case 2:
x = pop(&top);
if (x != -1)
{
printf("Popped Element = %d\n", x);
}
break;
case 3:
display(top);
break;
case 4:
exit(0);
default:
printf("Invalid Choice, Try Again.\n");
break;
}
}

return 0;
}
Exercise 5: Stack Operations
ii) Write a program to evaluate a postfix expression using a stack.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 50

void push(int stack[], int *top, int x)


{
if (*top >= MAX - 1)
{
printf("Stack Overflow.\n");
return;
}
(*top)++;
stack[*top] = x;
}

int pop(int stack[], int *top)


{
if (*top < 0)
{
printf("Stack Underflow.\n");
return -1;
}
int x = stack[*top];
(*top)--;
return x;
}

int evaluatePostfix(char *exp)


{
int stack[MAX];
int top = -1;
for (int i = 0; exp[i]; ++i)
{
if (isdigit(exp[i]))
{
push(stack, &top, exp[i] - '0');
}
else
{
int operand2 = pop(stack, &top);
int operand1 = pop(stack, &top);
switch (exp[i])
{
case '+':
push(stack, &top, operand1 + operand2);
break;
case '-':
push(stack, &top, operand1 - operand2);
break;
case '*':
push(stack, &top, operand1 * operand2);
break;
case '/':
push(stack, &top, operand1 / operand2);
break;
default:
printf("Invalid expression.\n");
return -1;
}
}
}
return pop(stack, &top);
}

int main()
{
char exp[MAX];
printf("Enter the postfix expression: ");
scanf("%s", exp);
int result = evaluatePostfix(exp);
if (result != -1)
{
printf("Result: %d\n", result);
}
return 0;
}
Exercise 5: Stack Operations
iii) Implement a program to check for balanced parentheses using a stack.
#include <stdio.h>
#include <stdlib.h>

#define MAX 50

void push(char stack[], int *top, char x)


{
if (*top >= MAX - 1)
{
printf("Stack Overflow.\n");
return;
}
(*top)++;
stack[*top] = x;
}

char pop(char stack[], int *top)


{
if (*top < 0)
{
printf("Stack Underflow.\n");
return '\0';
}
char x = stack[*top];
(*top)--;
return x;
}

int areParenthesesBalanced(char exp[])


{
char stack[MAX];
int top = -1;
for (int i = 0; exp[i] != '\0'; i++)
{
if (exp[i] == '(')
{
push(stack, &top, exp[i]);
}
else if (exp[i] == ')')
{
if (top == -1)
{
return 0;
}
pop(stack, &top);
}
}
return top == -1;
}

int main()
{
char exp[MAX];
printf("Enter expression with parentheses: ");
scanf("%s", exp);
if (areParenthesesBalanced(exp))
{
printf("Parentheses are balanced.\n");
}
else
{
printf("Parentheses are not balanced.\n");
}
return 0;
}
Exercise 6: Queue Operations
i) Implement a queue using arrays and linked lists.
A) queue using arrays.
#include<stdio.h>
#include<stdlib.h>
#define QMAX 5
void ENQUEUE(int *Q, int *front,int *rear,int x)
{
if(*rear==QMAX-1)
{
printf("Queue Overflow.\n");
return;
}
if(*rear==-1)
{
*front=*rear=0;
}
else
{
*rear=*rear+1;
}
Q[*rear]=x;
}

int DEQUEUE(int *Q,int *front,int *rear)


{
int x;
if(*front==-1)
{
printf("Queue Underflow.\n");
return -1;
}
x=Q[*front];
if(*front==*rear)
{
*front=*rear=-1;
}
*front=*front+1;
return x;
}

void display(int *Q,int front,int rear)


{
int i;
if(front==-1)
{
printf("Queue Underflow.\n");
return;
}
for(i=front;i<=rear;i++)
{
printf("%d\t",Q[i]);
}
}

int main()
{
int ch;
int x,front=-1,rear=-1;
int Q[10];
while(1)
{
printf("\n......Queue Menu......\n");
printf("Enqueue........1\n");
printf("Dequeue........2\n");
printf("Display........3\n");
printf("Exit...........4\n");
printf("Enter Your Choice(1-4):");
scanf("%d",&ch);
switch(ch)
{
default: printf("Invalid Choice, Try Again.\n");
break;
case 1: printf("Enter Queue Element:");
scanf("%d",&x);
ENQUEUE(Q,&front,&rear,x);
break;
case 2: x=DEQUEUE(Q,&front,&rear);
if(x!=-1)
{
printf("Poped Element=%d\n",x);
}
break;
case 3: display(Q,front,rear);
break;

case 4:exit(0);
}
}
}

B) queue using linked lists.


#include<stdio.h>
#include<stdlib.h>

typedef struct node {


int data;
struct node* link;
} node;

node* front = NULL;


node* rear = NULL;

void enqueue(int data)


{
node* newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->link = NULL;

if (rear == NULL)
{
front = rear = newNode;
return;
}

rear->link = newNode;
rear = newNode;
}

int dequeue()
{
if (front == NULL)
return -1;
node* temp = front;
int data = temp->data;

front = front->link;

if (front == NULL)
rear = NULL;

free(temp);
return data;
}

void display()
{
node* temp = front;
if (temp == NULL)
{
printf("Queue is empty.\n");
return;
}

printf("Queue elements: ");


while (temp != NULL)
{
printf("%d ", temp->data);
temp = temp->link;
}
printf("\n");
}

int main()
{
int ch, data;

while (1)
{
printf("\n......Queue Menu......\n");
printf("Enqueue........1\n");
printf("Dequeue........2\n");
printf("Display........3\n");
printf("Exit...........4\n");
printf("Enter Your Choice(1-4): ");
scanf("%d", &ch);

switch (ch)
{
case 1: {
printf("Enter Queue Element: ");
scanf("%d", &data);
enqueue(data);
break;
}
case 2: {
data = dequeue();
if (data != -1)
printf("Dequeued Element: %d\n", data);
else
printf("Queue is empty.\n");
break;
}
case 3: {
display();
break;
}
case 4: {
exit(0);
}
default: {
printf("Invalid Choice, Try Again.\n");
}
}
}
return 0;
}
Exercise 6: Queue Operations
ii) Solve problems involving circular queues.
#include<stdio.h>
#include<stdlib.h>
#define CQMAX 5
void CQENQUEUE(int *CQ, int *front,int *rear,int x)
{
if(*front==(*rear+1)%CQMAX)
{
printf("Circular Queue Overflow.\n");
return;
}
if(*rear==-1)
{
*front=*rear=0;
}
else
{
*rear=(*rear+1)%CQMAX;
}
CQ[*rear]=x;
}

int CQDEQUEUE(int *CQ,int *front,int *rear)


{
int x;
if(*front==-1)
{
printf("Circular Queue Underflow.\n");
return -1;
}
x=CQ[*front];
if(*front==*rear)
{
*front=*rear=-1;
}
else
{
*front=(*front+1)%CQMAX;
}
return x;
}

void display(int *CQ,int front,int rear)


{
int i;
if(front==-1)
{
printf("Circular Queue Underflow.\n");
return;
}
i=front;
while(1)
{
printf("%d\t",CQ[i]);
if(i==rear) break;
i=(i+1)%CQMAX;
}
}

int main()
{
int ch;
int x,front=-1,rear=-1;
int CQ[10];
while(1)
{
printf("\n......Circular Queue Menu......\n");
printf("CQEnqueue........1\n");
printf("CQDequeue........2\n");
printf("CQDisplay........3\n");
printf("Exit...........4\n");
printf("Enter Your Choice(1-4):");
scanf("%d",&ch);
switch(ch)
{
default: printf("Invalid Choice, Try Again.\n");
break;
case 1: printf("Enter CQueue Element:");
scanf("%d",&x);
CQENQUEUE(CQ,&front,&rear,x);
break;
case 2: x=CQDEQUEUE(CQ,&front,&rear);
if(x!=-1)
{
printf("Poped Element=%d\n",x);
}
break;
case 3: display(CQ,front,rear);
break;

case 4:exit(0);
}
}
}
Exercise 7: Stack and Queue Applications
i) Use a stack to evaluate an infix expression and convert it to postfix.
#include <stdio.h>

#define MAX 50

int push(char stack[], int *top, char x)


{
if (*top >= MAX - 1)
{
printf("Stack Overflow.\n");
return 0;
}
(*top)++;
stack[*top] = x;
return 1;
}

char pop(char stack[], int *top)


{
if (*top < 0)
{
printf("Stack Underflow.\n");
return '\0';
}
char x = stack[*top];
(*top)--;
return x;
}

int precedence(char op)


{
if (op == '+' || op == '-')
{
return 1;
}
else if (op == '*' || op == '/')
{
return 2;
}
return 0;
}

int infixToPostfix(char infix[], char postfix[])


{
char stack[MAX];
int top = -1;
int j = 0;
for (int i = 0; infix[i] != '\0'; i++)
{
char ch = infix[i];
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
{
postfix[j++] = ch;
}
else if (ch == '(')
{
if (!push(stack, &top, ch))
{
return 0;
}
}
else if (ch == ')')
{
while (top != -1 && stack[top] != '(')
{
postfix[j++] = pop(stack, &top);
}
if (top == -1)
{
printf("Invalid expression. Mismatched parentheses.\n");
return 0;
}
pop(stack, &top);
}
else
{
while (top != -1 && precedence(ch) <= precedence(stack[top]))
{
postfix[j++] = pop(stack, &top);
}
if (!push(stack, &top, ch))
{
return 0;
}
}
}
while (top != -1)
{
if (stack[top] == '(')
{
printf("Invalid expression. Mismatched parentheses.\n");
return 0;
}
postfix[j++] = pop(stack, &top);
}
postfix[j] = '\0';
return 1;
}

int main()
{
char infix[MAX], postfix[MAX];
printf("Enter infix expression: ");
scanf("%s", infix);
if (infixToPostfix(infix, postfix))
{
printf("Postfix expression: %s\n", postfix);
}
return 0;
}
Exercise 7: Stack and Queue Applications
ii) Create a program to determine whether a given string is a palindrome or not.
/*Exercise 7(ii): Stack Application:Create a program to determine whether a given
string is a palindrome or not.*/
#include <stdio.h>

#define MAX_SIZE 100

int top = -1;


char stack[MAX_SIZE];

void push(char item)


{
if(top == MAX_SIZE - 1)
{
printf("Stack Overflow\n");
}
else
{
top++;
stack[top] = item;
}
}

char pop()
{
if(top == -1)
{
printf("Stack Underflow\n");
}
else
{
return stack[top--];
}
}

int is_palindrome(char input_string[])


{
int i=0;

while(input_string[i])
{
push(input_string[i]);
i=i+1;
}
i=0;
while(input_string[i])
{
if (input_string[i] != pop())
{
return 0;
}
i=i+1;
}

return 1;
}
int main()
{
char input_string[MAX_SIZE];
printf("Enter a string: ");
scanf("%s", input_string);

if(is_palindrome(input_string))
{
printf("%s is a palindrome.\n", input_string);
}
else
{
printf("%s is not a palindrome.\n", input_string);
}

return 0;
}
Exercise 7: Stack and Queue Applications
iii) Implement a stack or queue to perform comparison and check for symmetry.

#include <stdio.h>

#define MAX 50

typedef struct {
int items[MAX];
int front;
int rear;
} Queue;

void initQueue(Queue *q)


{
q->front = -1;
q->rear = -1;
}

int isQueueEmpty(Queue *q)


{
return (q->front == -1 && q->rear == -1);
}

int isQueueFull(Queue *q)


{
return (q->rear == MAX - 1);
}

void enqueue(Queue *q, int value)


{
if (isQueueFull(q))
{
printf("Queue is full. Cannot enqueue.\n");
return;
}
if (isQueueEmpty(q))
{
q->front = 0;
}
q->rear++;
q->items[q->rear] = value;
}

int dequeue(Queue *q)


{
if (isQueueEmpty(q))
{
printf("Queue is empty. Cannot dequeue.\n");
return -1;
}
int removed = q->items[q->front];
if (q->front == q->rear)
{
q->front = -1;
q->rear = -1;
}
else
{
q->front++;
}
return removed;
}

int checkSymmetry(int arr[], int size)


{
Queue q;
initQueue(&q);

int i, mid = size / 2;


for (i = 0; i < mid; i++)
{
enqueue(&q, arr[i]);
}

if (size % 2 != 0)
{
i++;
}

while (i < size && !isQueueEmpty(&q))


{
int dequeued = dequeue(&q);
if (dequeued != arr[i])
{
return 0;
}
i++;
}

return isQueueEmpty(&q);
}

int main()
{
int arr[MAX];
int size;

printf("Enter the size of the array: ");


scanf("%d", &size);

printf("Enter the elements of the array: ");


for (int i = 0; i < size; i++)
{
scanf("%d", &arr[i]);
}

if (checkSymmetry(arr, size))
{
printf("The array is symmetric.\n");
}
else
{
printf("The array is not symmetric.\n");
}

return 0;
}
Exercise 8: Binary Search Tree
i) Implementing a BST using Linked List.
ii) Traversing of BST.
#include<stdio.h>
#include<stdlib.h>

typedef struct bstnode


{
struct bstnode *lchild;
int key;
struct bstnode *rchild;
} bstnode;

bstnode* bstSearch(bstnode *root, int x) {


bstnode *p;
p = root;
while (p != NULL && p->key != x) {
if (x < p->key)
p = p->lchild;
else
p = p->rchild;
}
if (p == NULL) {
printf("Key Not Found.\n");
return NULL;
}
return p;
}

bstnode* bstInsertion(bstnode *root, int x) {


bstnode *new, *parent, *p;
if (root == NULL) {
root = (bstnode*)malloc(sizeof(bstnode));
root->key = x;
root->lchild = root->rchild = NULL;
}
else {
p = root;
parent = NULL;
while (p != NULL) {
parent = p;
if (x < p->key)
p = p->lchild;
else if (x > p->key)
p = p->rchild;
}
new = (bstnode*)malloc(sizeof(bstnode));
new->key = x;
new->lchild = new->rchild = NULL;
if (x < parent->key)
parent->lchild = new;
else
parent->rchild = new;
}
return root;
}
bstnode* findMin(bstnode* node) {
bstnode* current = node;
while (current && current->lchild != NULL)
current = current->lchild;
return current;
}

bstnode* bstDeletion(bstnode* root, int key) {


if (root == NULL)
return root;
if (key < root->key)
root->lchild = bstDeletion(root->lchild, key);
else if (key > root->key)
root->rchild = bstDeletion(root->rchild, key);
else {
if (root->lchild == NULL) {
bstnode* temp = root->rchild;
free(root);
return temp;
}
else if (root->rchild == NULL) {
bstnode* temp = root->lchild;
free(root);
return temp;
}
bstnode* temp = findMin(root->rchild);
root->key = temp->key;
root->rchild = bstDeletion(root->rchild, temp->key);
}
return root;
}

void inorder(bstnode *root) {


bstnode *p = root;
if (p != NULL) {
inorder(p->lchild);
printf("%d\t", p->key);
inorder(p->rchild);
}
}

void preorder(bstnode *root) {


bstnode *p = root;
if (p != NULL) {
printf("%d\t", p->key);
preorder(p->lchild);
preorder(p->rchild);
}
}

void postorder(bstnode *root) {


bstnode *p = root;
if (p != NULL) {
postorder(p->lchild);
postorder(p->rchild);
printf("%d\t", p->key);
}
}
int main() {
bstnode *root = NULL, *p;
int x, ch;
while (1) {
printf("\n......BST Menu......\n");
printf("BST Insertion........1\n");
printf("BST Deletion.........2\n");
printf("BST Search...........3\n");
printf("BST Traversals.......4\n");
printf("Exit.................5\n");
printf("Enter Your Choice(1-5):");
scanf("%d", &ch);
switch (ch) {
default: printf("Invalid Choice, Try Again.\n");
break;
case 1:
printf("Enter Leaf Node Element:");
scanf("%d", &x);
root = bstInsertion(root, x);
break;
case 2:
printf("Enter Node to Delete:");
scanf("%d", &x);
root = bstDeletion(root, x);
break;
case 3:
printf("Enter Node to Search:");
scanf("%d", &x);
p = bstSearch(root, x);
if (p == NULL) {
printf("Key Not Found");
}
else {
printf("Key Found at:%X\n", p);
}
break;
case 4:
printf("\nBST Traversals:\n");
printf("\nINORDER:");
inorder(root);
printf("\nPRE ORDER:");
preorder(root);
printf("\nPOST ORDER:");
postorder(root);
break;
case 5: exit(0);
}
}
return 0;
}
Exercise 9: Hashing
i) Implement a hash table with collision resolution techniques.
#include <stdio.h>
#include <stdlib.h>

#define TABLE_SIZE 10

// Structure for linked list node


struct Node {
int key;
int value;
struct Node* next;
};

// Structure for hash table


struct HashTable {
struct Node* table[TABLE_SIZE];
};

// Function to create a new node


struct Node* createNode(int key, int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->key = key;
newNode->value = value;
newNode->next = NULL;
return newNode;
}

// Function to create a new hash table


struct HashTable* createHashTable() {
struct HashTable* hashTable = (struct HashTable*)malloc(sizeof(struct
HashTable));
for (int i = 0; i < TABLE_SIZE; i++) {
hashTable->table[i] = NULL;
}
return hashTable;
}

// Function to calculate hash value


int hash(int key) {
return key % TABLE_SIZE;
}

// Function to insert a key-value pair into the hash table


void insert(struct HashTable* hashTable, int key, int value) {
int index = hash(key);
struct Node* newNode = createNode(key, value);
if (hashTable->table[index] == NULL) {
hashTable->table[index] = newNode;
} else {
struct Node* temp = hashTable->table[index];
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}
// Function to search for a key in the hash table and return its value
int search(struct HashTable* hashTable, int key) {
int index = hash(key);
struct Node* temp = hashTable->table[index];
while (temp != NULL) {
if (temp->key == key) {
return temp->value;
}
temp = temp->next;
}
return -1; // Key not found
}

// Function to display the hash table


void display(struct HashTable* hashTable) {
for (int i = 0; i < TABLE_SIZE; i++) {
printf("Bucket %d: ", i);
struct Node* temp = hashTable->table[i];
while (temp != NULL) {
printf("(%d, %d) -> ", temp->key, temp->value);
temp = temp->next;
}
printf("NULL\n");
}
}

int main() {
struct HashTable* hashTable = createHashTable();

// Inserting key-value pairs


insert(hashTable, 5, 50);
insert(hashTable, 15, 150);
insert(hashTable, 25, 250);
insert(hashTable, 35, 350);
insert(hashTable, 45, 450);

// Displaying the hash table


display(hashTable);

// Searching for a key


int keyToSearch = 25;
int value = search(hashTable, keyToSearch);
if (value != -1) {
printf("Value for key %d is %d\n", keyToSearch, value);
} else {
printf("Key %d not found\n", keyToSearch);
}

return 0;
}
Exercise 9: Hashing
ii) Write a program to implement a simple cache using hashing.
#include <stdio.h>
#include <stdlib.h>

#define CACHE_SIZE 5

struct CacheNode
{
int key;
int value;
struct CacheNode* next;
};

struct Cache
{
struct CacheNode* table[CACHE_SIZE];
};

struct CacheNode* createCacheNode(int key, int value)


{
struct CacheNode* newNode = (struct CacheNode*)malloc(sizeof(struct CacheNode));
if (newNode == NULL)
{
fprintf(stderr, "Memory allocation failed.\n");
exit(1);
}
newNode->key = key;
newNode->value = value;
newNode->next = NULL;
return newNode;
}

struct Cache* createCache()


{
struct Cache* cache = (struct Cache*)malloc(sizeof(struct Cache));
if (cache == NULL)
{
fprintf(stderr, "Memory allocation failed.\n");
exit(1);
}
for (int i = 0; i < CACHE_SIZE; i++)
{
cache->table[i] = NULL;
}
return cache;
}

int hash(int key)


{
return key % CACHE_SIZE;
}

int get(struct Cache* cache, int key)


{
int index = hash(key);
struct CacheNode* temp = cache->table[index];
while (temp != NULL)
{
if (temp->key == key)
{
return temp->value;
}
temp = temp->next;
}
return -1;
}

void put(struct Cache* cache, int key, int value)


{
int index = hash(key);
struct CacheNode* newNode = createCacheNode(key, value);
if (cache->table[index] == NULL)
{
cache->table[index] = newNode;
}
else
{
struct CacheNode* temp = cache->table[index];
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newNode;
}
}

void display(struct Cache* cache)


{
for (int i = 0; i < CACHE_SIZE; i++)
{
printf("Bucket %d: ", i);
struct CacheNode* temp = cache->table[i];
while (temp != NULL)
{
printf("(%d, %d) -> ", temp->key, temp->value);
temp = temp->next;
}
printf("NULL\n");
}
}

int main()
{
struct Cache* cache = createCache();

put(cache, 1, 10);
put(cache, 2, 20);
put(cache, 3, 30);
put(cache, 4, 40);
put(cache, 5, 50);

display(cache);

int keyToRetrieve = 3;
int value = get(cache, keyToRetrieve);
if (value != -1)
{
printf("Value for key %d is %d\n", keyToRetrieve, value);
}
else
{
printf("Key %d not found\n", keyToRetrieve);
}

return 0;
}

You might also like