0% found this document useful (0 votes)
18 views46 pages

Arnav Babel - DS

Uploaded by

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

Arnav Babel - DS

Uploaded by

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

Arnav Babel

SE C11
12

EXPERIMENT 1
Implement Stack ADT using array.
Theory:

 A stack is a linear data structure that follows the Last In, First Out (LIFO) principle.
 This means that the last element added to the stack is the first one to be removed.

 The primary operations associated with a stack are:

1. Push: Adding an element to the top of the stack.

2. Pop: Removing the top element from the stack.

3. Peek: Viewing the top element without removing it.

4. IsEmpty: Checking if the stack is empty.

5. IsFull: Checks if the stack is full

 Applications of Stack implemented using array:


1. Function Call Management:
When a function is called, its parameters and local variables are pushed onto the
stack.
When the function returns, these items are popped off, allowing the program to
resume execution from the correct point.

2. Expression Evaluation:
Stacks are essential for parsing and evaluating arithmetic expressions.
Eg: converting infix expressions (like A + B) to postfix (like AB+) can be
efficiently done using stacks.

3. Parentheses Checker:
Stacks are used to check for balanced. They help ensure that opening and closing
symbols (like {}, [], ()) match correctly.
Program:

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 3
typedef struct
{
int stk[MAXSIZE];
int top;
}Stack;

void push(Stack *s,int element)


{
if((*s).top==(MAXSIZE-1))
printf("Stack if Full\n");
else
{
(*s).top=(*s).top+1;
(*s).stk[(*s).top]=element;
}
}

int pop(Stack *s)


{
int num;
if((*s).top==-1)
{
printf("Stack is Empty\n");
return -32768;
}
else
{
num=(*s).stk[(*s).top];
(*s).top=(*s).top-1;
return num;
}
}

void display(Stack s)
{
int i;
if(s.top==-1)
printf("Stack is Empty\n");
else
{
printf("Stack is:\n");
for(i=s.top;i>=0;i--)
{
printf("%d ",s.stk[i]);
}
printf("\n");
}
}

int main()
{

Stack s;
int option=1;
int choice;
int element,result;
s.top=-1;

while(option)
{
printf("STACK OPERATION:\n");
printf(" \n");
printf(" 1 -> PUSH \n");
printf(" 2 -> POP \n");
printf(" 3 -> DISPLAY \n");
printf(" 4 -> EXIT \n");
printf(" \n");

printf("Enter your choice:\n");


scanf("%d",&choice);

switch(choice)
{
case 1:
printf("Enter the element to pushed: ");
scanf("%d",&element);
push(&s,element);
break;

case 2:
result=pop(&s);
printf("Popped element is: %d",result);
break;

case 3:
display(s);
break;

case 4:
return 0;
}
}
}
Output:
Arnav Babel
SE C11
12

EXPERIMENT 2
Convert an Infix expression to Postfix expression using Stack ADT.
Theory:

 The infix to postfix conversion program is essential for various applications in


computing, such as expression evaluation, compiler design, and calculator
implementations.
 The program handles standard arithmetic operators, parentheses, and performs error
checking for invalid expressions.

 Calculators:
Many scientific calculators use postfix notation to simplify complex mathematical
expressions computation.
Benefit: Postfix expressions can be evaluated using a simple stack-based algorithm,
making calculations more efficient.

 Compilers:
In compiling expressions in programming languages, converting to postfix helps in
generating intermediate code.
Benefit: Postfix notation avoids the complexities of operator precedence and
parentheses, facilitating easier code generation.

 Educational Tools:
Teaching algorithms and data structures.
Benefit: Demonstrates how stacks are used in expression parsing and conversion,
which is a fundamental concept in computer science.
Program:

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

#define MAX 100

void InfixtoPostfix(char source[], char target[]); int


getPriority(char op);
void push(char st[], int *top, char val); char
pop(char st[], int *top);

int main() { char infix[MAX],


postfix[MAX];

printf("\nEnter any infix expression: "); if


(fgets(infix, sizeof(infix), stdin) != NULL) {
// Remove newline character if present
size_t len = strlen(infix); if (len > 0 &&
infix[len - 1] == '\n') {
infix[len - 1] = '\0';
}

strcpy(postfix, "");
InfixtoPostfix(infix, postfix);

printf("\nThe corresponding postfix expression is: ");


puts(postfix);
} else {
printf("\nError reading input.\n");
return 1;
}

return 0;
}
void InfixtoPostfix(char source[], char target[]) {
char st[MAX]; int top = -1;
int i = 0, j = 0;

strcpy(target, "");

while (source[i] != '\0') {


if (source[i] == '(') {
push(st, &top, source[i]);
i++;
} else if (source[i] == ')') {
while (top != -1 && st[top] != '(') {
target[j] = pop(st, &top);
j++;
}
if (top == -1) {
printf("\nINCORRECT EXPRESSION\n");
exit(1);

}
pop(st, &top); // remove left parenthesis
i++;
} else if (isdigit(source[i]) || isalpha(source[i])) {
target[j] = source[i];
j++;
i++;
} else if (source[i] == '+' || source[i] == '-' || source[i] == '*' || source[i] == '/' || source[i]
== '%') {
while (top != -1 && st[top] != '(' && getPriority(st[top]) >= getPriority(source[i])) {
target[j] = pop(st, &top);
j++;
}
push(st, &top, source[i]);
i++;
} else {
printf("\nINCORRECT ELEMENT IN EXPRESSION\n");
exit(1);
}
}

while (top != -1) {


if (st[top] == '(') {
printf("\nINCORRECT EXPRESSION\n");
exit(1);
}
target[j] = pop(st, &top);
j++;
}

target[j] = '\0';
}

int getPriority(char op) {


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

void push(char st[], int *top, char val) {


if (*top == MAX - 1) {
printf("\nSTACK OVERFLOW\n");
} else {
(*top)++;
st[*top] = val;
}
}

char pop(char st[], int *top) {


if (*top == -1) {
printf("\nSTACK UNDERFLOW\n");
return '\0'; } else {
char val = st[*top];
(*top)--;
return val;
}
}
Output:
Arnav Babel
SE C11
12

EXPERIMENT 3
Evaluate Postfix Expression using Stack ADT.
Theory:

 Evaluating postfix expressions using a stack is a classic algorithmic problem with


numerous practical applications.
 The stack's LIFO (Last In, First Out) nature makes it well-suited for handling the
sequential evaluation required for postfix expressions.
 Here are some use cases where evaluating postfix expressions using a stack ADT
(Abstract Data Type) can be highly useful:

 Basic Calculators:
Many calculators, especially older ones or specialized scientific calculators, use postfix
notation for user input to simplify computation. Evaluating postfix expressions using a
stack allows these calculators to efficiently compute results.

 Online Calculators:
Web-based calculators that support postfix notation can use stack-based evaluation for
processing user inputs.

 Compilers and Interpreters


Compilers and interpreters for programming languages often need to evaluate
expressions as part of their execution or optimization phases.
Using a stack to evaluate postfix expressions can streamline these processes.

 Software Development Tools


Some debugging tools or IDEs may need to evaluate postfix expressions for various
debugging or evaluation purposes.
Using a stack for this ensures that the evaluation is done efficiently and correctly.
Program:

#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#define MAX 100
float st[MAX];
int top=-1;
void push(float st[], float val);
float pop(float st[]);
float evaluatePostfixExp(char exp[]);
int main()
{
float val;
char exp[100];
printf("\nEnter any postfix expression : ");
gets(exp) ;
val = evaluatePostfixExp(exp);
printf("\nValue of the postfix expression = %.2f\n", val);
return 0;
}
float evaluatePostfixExp(char exp[])
{
int i=0;
float op1, op2, value;
while(exp[i]!='\0')
{
if(isdigit(exp[i]))
push(st, (float)(exp[i]-'0'));
else
{
op2 = pop(st);
op1 = pop(st);
switch(exp[i])
{
case '+':
value = op1 + op2;
break;
case '-':
value = op1 - op2;
break;
case '/':
value = op1 / op2;
break;
case '*':
value = op1 * op2;
break;
case '%':
value=(int)op1 % (int)op2;
break;
}
push(st, value);
}
i++;
}
return (pop(st));
}
void push(float st[], float val)
{
if(top==-MAX-1)
printf("\nSTACK OVERFLOW");
else
{
top++;
st[top]=val;
}
}
float pop (float st[])
{
float val=-1;
if(top==-1)
{
printf("\nSTACK UNDERFLOW");
return -1;
}
else
{
val=st[top];
top--;
}
return val;
}
Output:
Arnav Babel
SE C14
53

EXPERIMENT 4
Implement Linear Queue ADT using array.
Theory:

 A queue is a linear data structure that follows the First In, First Out (FIFO) principle.
 This means that the first element added to the queue will be the first one to be
removed.

 The primary operations associated with a linear queue are:

1. Enqueue: Add an element to the back of the queue.

2. Dequeue: Remove and return the front element of the queue.

3. Peek: View the front element without removing it.

4. Display: Show all elements in the queue.

5. IsEmpty: Check if the queue is empty.

6. IsFull: Checks if the queue is full

 Applications of linear queue implemented using array:


1. Print Queue:
When multiple print jobs are sent to a printer, they are queued to ensure they are
printed in the order received, preventing confusion and overlap.

2. Operating System:
Queues are essential for scheduling processes in an operating system. Tasks are
added to a queue and executed in the order they arrive, ensuring fairness.

3. Data Buffering:
Queues are used to manage data streams, buffering data packets as they arrive and
processing them in the order they were received.

4. Call Centers:
Customers are managed in a queue to ensure they are attended to in the order they
arrive, enhancing service efficiency and customer satisfaction.
Program:

#include<stdio.h>
#include<stdlib.h>
#define MAX 10
int queue[MAX];
int front=-1,rear=-1;

void enqueue(int element)


{
if(rear==MAX-1)
printf("Queue Overflow");
else if(front==-1&&rear==-1)
front=rear=0;
else
rear++;
queue[rear]=element;
}

int dequeue()
{
if(front==-1||front>rear){
printf("Queue Underflow");
return -1;
}
else{
int value;
value=queue[front];
front++;
if(front>rear){
front=rear=-1;
}
return value;
}
}

int peek()
{
if(front==-1||front>rear){
printf("Queue Empty");
return -1;
}
else{
return queue[front];
}
}

void display()
{
int i;
if(front==-1||front>rear)
printf("Queue Empty");
else{
for(i=front;i<=rear;i++){
printf("\t%d",queue[i]);
}
}
}

int main()
{
int element,value;
int choice;
while(1){
printf("\n-----MENU ---- \n");
printf("1.ENQUEUE\n2.DEQUEUE\n3.PEEK\n4.DISPLAY\n5.EXIT\n");
printf("\nEnter Choice Number: ");
scanf("%d",&choice);
switch(choice){
case 1:
printf("Enter the element to be inserted: ");
scanf("%d",&element);
enqueue(element);
break;

case 2:
value=dequeue();
printf("Deleted element is: %d",value);
break;

case 3:
value=peek();
printf("Front Element is: %d",value);
break;

case 4:
display();
break;

case 5:
exit(1);
}
}
}
Output:
Arnav Babel
SE C11
12

EXPERIMENT 5
Implement Circular Queue ADT using array.
Theory:

 A circular queue is an extended version of a normal queue where the last element of
the queue is connected to the first element of the queue forming a circle.
 It is also based on First In First Out (FIFO) principle.

 The primary operations associated with a linear queue are:

1. Insert: Add an element to the rear of the queue.

2. Delete: Remove and return the front element.

3. Peek: View the front element without removing it.

4. Display: Show all elements in the queue.

 Applications of circular queue implemented using array:


1. Print Queue:
When multiple print jobs are sent to a printer, they are queued to ensure they are
printed in the order received, preventing confusion and overlap.

2. Operating System:
Queues are essential for scheduling processes in an operating system. Tasks are
added to a queue and executed in the order they arrive, ensuring fairness.

3. Network Buffers:
Circular queues are used in network routers to manage incoming packets,
preventing overflow and ensuring smooth data transmission.
Program:

#include <stdio.h>
#define MAX 10

int queue[MAX];
int front= -1, rear= -1;
void insert(void);
int delete_element(void);
int peek(void);
void display(void);

int main()
{
int option, val;
do
{
printf("\nMAIN MENU");
printf("\n 1. Insert an element");
printf("\n 2. Delete an element");
printf("\n 3. Peek");
printf("\n 4. Display the queue");
printf("\n 5. EXIT");
printf("\n Enter your option: ");
scanf("%d", &option);
switch(option)
{
case 1:
insert();
break;

case 2:
val = delete_element();
if(val!=-1)
printf("\n The number deleted is : %d", val);
break;

case 3:
val = peek();
if(val!=-1)
printf("\n The first value in queue is : %d", val);
break;

case 4:
display();
break;
}
}while(option!=5);
return 0;
}

void insert()
{
int num;
printf("\n Enter the number to be inserted in the queue : ");
scanf("%d", &num);
if(front==0 && rear==MAX-1)
printf("\n OVERFLOW");
else if(front==-1 && rear==-1)
{
front=rear=0;
queue[rear]=num;
}
else if(rear==MAX-1 && front!=0)
{
rear=0;
queue[rear]=num;
}
else
{
rear++;
queue[rear]=num;
}
}

int delete_element()
{
int val;
if(front==-1 && rear==-1)
{
printf("\n UNDERFLOW");
return -1;
}
val = queue[front];
if(front==rear)
front=rear=-1;
else
{
if(front==MAX-1)
front=0;
else
front++;
}
return val;
}

int peek()
{
if(front== -1 && rear== -1)
{
printf("\n QUEUE IS EMPTY");
return -1;
}
else
{
return queue[front];
}
}

void display()
{
int i;
printf("\n");
if (front == -1 && rear== -1)
printf ("\n QUEUE IS EMPTY");
else
{
if(front<=rear)
{
for(i=front;i<=rear;i++)
printf("\t %d", queue[i]);
}
else
{
for(i=front;i<MAX;i++)
printf("\t %d", queue[i]);
for(i=0;i<=rear;i++)
printf("\t %d", queue[i]);
}
}
}
Output:
Arnav Babel
SE C11
12

EXPERIMENT 6a
Implement Singly Linked List ADT.
Theory:

 A linked list is a linear data structure where each element (node) contains a data part
and a pointer (link) to the next node in the sequence.
 Unlike arrays, linked lists do not require contiguous memory locations.

 Advantages of linked lists:


1. Dynamic Size:
You can grow or shrink the list as needed.

2. Efficient Insertions/Deletions:
Adding or removing elements is straightforward, especially at the beginning or
end of the list.

3. Memory Utilization:
Memory is allocated on demand.
Program:

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct Node
{
int data;
struct Node *next;
};
struct Node *start=NULL;

struct Node *create_ll()


{
struct Node *new_node, *ptr;
int num;
printf("\nEnter -1 to End");
printf("\nEnter the data: ");
scanf("%d",&num);
while(num!=-1)
{
new_node=(struct Node*)malloc(sizeof(struct Node));
new_node->data=num;
if(start==NULL)
{
new_node->next=NULL;
start=new_node;
}
else
{
ptr=start;
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=new_node;
new_node->next=NULL;
}
printf("\nEnter the data: ");
scanf("%d",&num);
}
return start;
}

struct Node *display()


{
struct Node *ptr;
ptr=start;
while(ptr!=NULL)
{
printf("\t%d",ptr->data);
ptr=ptr->next;
}
return start;
}

struct Node *insert_beg()


{
struct Node *new_node;
int num;
printf("\nEnter the data: ");
scanf("%d",&num);
new_node=(struct Node*)malloc(sizeof(struct Node));
new_node->data=num;
new_node->next=start;
start=new_node;
return start;
}

struct Node *insert_end()


{
struct Node *ptr,*new_node;
int num;
printf("\nEnter the data: ");
scanf("%d",&num);
new_node=(struct Node*)malloc(sizeof(struct Node));
new_node->data=num;
new_node->next=NULL;
ptr=start;
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=new_node;
return start;
}

struct Node *insert_before()


{
struct Node *new_node,*ptr,*preptr;
int num,val;
printf("\nEnter the data: ");
scanf("%d",&num);
printf("\nEnter the value before which the data has to be inserted: ");
scanf("%d",&val);
new_node=(struct Node*)malloc(sizeof(struct Node));
new_node->data=num;
ptr=start;
while(ptr->data!=val)
{
preptr=ptr;
ptr=ptr->next;
}
preptr->next=new_node;
new_node->next=ptr;
return start;
}

struct Node *insert_after()


{
struct Node *new_node,*ptr,*preptr;
int num,val;
printf("\nEnter the data: ");
scanf("%d",&num);
printf("\nEnter the value after which the data has to be inserted: ");
scanf("%d",&val);
new_node=(struct Node*)malloc(sizeof(struct Node));
new_node->data=num;
ptr=start;
while(preptr->data!=val)
{
preptr=ptr;
ptr=ptr->next;
}
preptr->next=new_node;
new_node->next=ptr;
return start;
}

struct Node *delete_beg()


{
struct Node *ptr;
ptr=start;
start=start->next;
free(ptr);
return start;
}

struct Node *delete_end()


{
struct Node *ptr,*preptr;
ptr=start;
while(ptr->next!=NULL)
{
preptr=ptr;
ptr=ptr->next;
}
preptr->next=NULL;
free(ptr);
return start;
}

struct Node *delete_node()


{
struct Node *ptr,*preptr;
int val;
printf("\nEnter the value of the node which has to be deleted: ");
scanf("%d",&val);
ptr=start;
if(ptr->data==val)
{
start=delete_beg(start);
return start;
}
else
{
while(ptr->data!=val)
{
preptr=ptr;
ptr=ptr->next;
}
preptr->next=ptr->next;
free(ptr);
return start;
}
}

struct Node *delete_after()


{
struct Node *ptr,*preptr;
int val;
printf("\nEnter the value after which the node has to be deleted: ");
scanf("%d",&val);
ptr=start;
preptr=ptr;
while(preptr->data!=val)
{
preptr=ptr;
ptr=ptr->next;
}
preptr->next=ptr->next;
free(ptr);
return start;
}

struct Node *delete_list()


{
struct Node *ptr;
if(start!=NULL)
{
ptr=start;
while(ptr!=NULL)
{
printf("\n%d is to be deleted next",ptr->data);
start=delete_beg(ptr);
ptr=start;
}
}
return start;
}

struct Node *sort_list()


{
struct Node *ptr1,*ptr2;
int temp;
ptr1=start;
while(ptr1->next!=NULL)
{
ptr2=ptr1->next;
while(ptr2!=NULL)
{
if(ptr1->data > ptr2->data)
{
temp=ptr1->data;
ptr1->data=ptr2->data;
ptr2->data=temp;
}
ptr2=ptr2->next;
}
ptr1=ptr1->next;
}
return start;
}

int main()
{
int option;
while(1)
{
printf("\n-------MENU ------ ");
printf("\n1. Insert beg\n2. Insert end\n3. Insert bef\n4. Insert after\n5. Delete
beg\n6. Delete end\n7. Delete specific\n8. Delete after\n9. Delete list\n10. Sort list\n11.
Create list\n12. Display list\n13. Exit\n\n");
printf("Enter option: ");
scanf("%d",&option);
switch(option)
{
case 1:
start=insert_beg();
break;
case 2:
start=insert_end();
break;
case 3:
start=insert_before();
break;
case 4:
start=insert_after();
break;
case 5:
start=delete_beg();
break;
case 6:
start=delete_end();
break;
case 7:
start=delete_node();
break;
case 8:
start=delete_after();
break;
case 9:
start=delete_list();
break;
case 10:
start=sort_list();
break;
case 11:
start=create_ll();
break;
case 12:
start=display();
break;
case 13:
exit(0);
}
}
return 0;
}
Output:
Arnav Babel
SE C11
12

EXPERIMENT 6b
Implement Circular Linked List ADT.
Theory:

 A circular linked list is a variation of a linked list in which all nodes are connected in a
circular manner.
 The next pointer of last node points back to the first node and this results in forming a
circle.
 In this type of Linked list, we can only move through the list in one direction.
 This structure can be either singly linked (one pointer to the next node) or doubly
linked (two pointers, one to the next node and another to the previous node).

 Advantages of circular linked lists:


1. Efficient Traversal:
You can start from any node and traverse the entire list without worrying about
reaching an end.

2. Memory Management:
Suitable for applications where the size of the list can change frequently.
Program:

#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *tail=NULL;
void create(int val)
{
struct node *nn=(struct node*)malloc(sizeof(struct node));
nn->data=val;
nn->next=NULL;
if(tail==NULL)
{
tail=nn;
tail->next=nn;
}
else
{
nn->next=tail->next;
tail->next=nn;
tail=nn;
}
}

void display()
{
struct node *ptr=tail->next;
int count=0;
do
{
printf("%d ",ptr->data);
count++;
ptr=ptr->next;
}while(ptr!=tail->next);
printf("\nNo. of nodes are: %d\n",count);
}

void insert_beg(int val)


{
struct node *nn=(struct node*)malloc(sizeof(struct node));
nn->data=val;
nn->next=NULL;
if(tail==NULL)
{
tail=nn;
tail->next=nn;
}
else
{
nn->next=tail->next;
tail->next=nn;
}
}

void insert_end(int val)


{
struct node *nn=(struct node*)malloc(sizeof(struct node));
nn->data=val;
nn->next=NULL;
if(tail==NULL)
{
tail=nn;
tail->next=nn;
}
else
{
nn->next=tail->next;
tail->next=nn;
tail=nn;
}
}

void insert_pos(int val,int pos)


{
struct node *nn=(struct node*)malloc(sizeof(struct node));
nn->data=val;
nn->next=NULL;
if(tail==NULL)
{
tail=nn;
tail->next=nn;
}
else
{
if(pos==1)
insert_beg(val);
else
{
struct node *ptr=tail->next;
while(pos>2 && ptr!=tail)
{
ptr=ptr->next;
pos--;
}
if(ptr==tail)
{
insert_end(val);
}
else
{
nn->next=ptr->next;
ptr->next=nn;
//nn=NULL;
}
}
}
}

int delete_beg()
{
int delnum=0;
if(tail==NULL)
{
printf("\nLinked List is empty\n");
}
else if(tail->next==tail)
{
delnum=tail->data;
free(tail);
tail=NULL;
}
else
{
struct node *temp=tail->next;
delnum=temp->data;
tail->next=temp->next;
free(temp);
temp=NULL;
}

return delnum;
}
int delete_end()
{
int delnum=0;
if(tail==NULL)
{
printf("\nLinked List is empty\n");
}
else if(tail->next==tail)
{
delnum=tail->data;
free(tail);
tail=NULL;
}
else
{
struct node *ptr=tail->next;
while(ptr->next!=tail)
ptr=ptr->next;
ptr->next=tail->next;
delnum=tail->data;
free(tail);
tail=ptr;

}
return delnum;
}
int delete_pos(int pos)
{
int delnum=0;
if(tail==NULL)
{
printf("\nLinked List is empty\n");
}
else if(tail->next==tail)
{
delnum=tail->data;
free(tail);
tail=NULL;
}
else
{
if(pos==1)
delete_beg(pos);
else
{
struct node *temp;
struct node *ptr=tail->next;
while(pos>1 && ptr!=tail)
{
temp=ptr;
ptr=ptr->next;
pos--;
}
if(pos!=1)
{
printf("Position out of Bound.\nElement will be deleted at the
end.\n");
}
if(ptr==tail)
{
delnum=delete_end();
}
else
{
delnum=ptr->data;
temp->next=ptr->next;
free(ptr);
ptr=NULL;
}
}
}

return delnum;
}
int main()
{
int c=50,val,p,n;
while(c!=0)
{
printf("\n-----MENU ---- \n1:Create\n2:display\n3:Insert at beginning\n4:Insert
at end\n5:Insert at position\n6:Delete at beginning\n7:Delete at end\n8:Delete at
position\n0:Exit\n");
printf("Enter you choice: ");
scanf("%d",&c);
switch(c)
{
case 1:
printf("\nEnter number of nodes that you want to create: ");
scanf("%d",&n);
for(int i=0;i<n;i++)
{
printf("Enter value: ");
scanf("%d",&val);
create(val);
}
break;
case 2:
display();
break;
case 3:
printf("Enter value to insert: ");
scanf("%d",&val);
insert_beg(val);
break;
case 4:
printf("Enter value to insert: ");
scanf("%d",&val);
insert_end(val);
break;
case 5:
printf("Enter value to insert: ");
scanf("%d",&val);
printf("Enter position: ");
scanf("%d",&p);
insert_pos(val,p);
break;
case 6:
printf("\nDeleted number is : %d",delete_beg());
break;
case 7:
printf("\nDeleted number is : %d",delete_end());
break;
case 8:
printf("Enter position: ");
scanf("%d",&p);
printf("\nDeleted number: %d",delete_pos(p));

case 0:
break;
default:
printf("\nInvalid Input");
}
}
return 0;
}
Output:
Arnav Babel
SE C11
12

EXPERIMENT 7
Implement Stack/Linear Queue ADT using Linked List.
Theory:

 The stack Abstract Data Type (ADT) is a collection that follows the Last In, First Out
(LIFO) principle, meaning the most recently added element is the first one to be
removed.
 The main operations for a stack implemented using a linked list are:
1. Push: Add an element to the top of the stack.

2. Pop: Remove and return the top element of the stack.

3. Peek: Return the top element without removing it.

4. isEmpty: Check if the stack is empty.

5. isFull: Check if the stack is full.

6. Display: Print the elements in the stack.

 The queue Abstract Data Type (ADT) is a collection that follows the First In, First Out
(FIFO) principle, meaning the first element added is the first one to be removed.
 The main operations for a queue implemented using a linked list are:
1. Enqueue: Add an element to the back of the queue.

2. Dequeue: Remove and return the front element of the queue.

3. Peek: Return the front element without removing it.

4. isEmpty: Check if the queue is empty.

5. isFull: Check if the queue is full.

6. Display: Print the elements in the queue.

 Advantages of Linked List Implementation:


1. Dynamic Size:
The stack/queue can grow and shrink as needed without a fixed limit, unlike an
array-based implementation.

2. No Wasted Space:
Memory is allocated only for the elements in the stack/queue.
Program (stack):

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

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

void push(struct Node** top, int data) {


struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Stack Overflow\n");
return;
}
newNode->data = data;
newNode->next = *top;
*top = newNode;
printf("%d pushed to stack\n", data);
}

int pop(struct Node** top) {


if (*top == NULL) {
printf("Stack Underflow\n");
return -1;
}
struct Node* temp = *top;
*top = (*top)->next;
int popped = temp->data;
free(temp);
printf("%d popped from stack\n", popped);
return popped;
}

void displayStack(struct Node* top) {


if (top == NULL) {
printf("Stack is empty\n");
return;
}
printf("Stack elements: ");
while (top != NULL) {
printf("%d ", top->data);
top = top->next;
}
printf("\n");
}
int main() {
struct Node* stack = NULL;
int choice, value;

do {
printf("\n--- Stack Menu ---\n");
printf("1. Push\n");
printf("2. Pop\n");
printf("3. Display\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);

switch (choice) {
case 1:
printf("Enter the value to push: ");
scanf("%d", &value);
push(&stack, value);
break;
case 2:
pop(&stack);
break;
case 3:
displayStack(stack);
break;
case 4:
printf("Exiting...\n");
break;
default:
printf("Invalid choice! Please try again.\n");
}
} while (choice != 4);

return 0;
}
Output:

You might also like