Sr. Problem Statement                                                                   Pg.
No+4
N
o
1.   Write a code for infix to postfix                                                  1-4
2.   Write a code for infix to prefix                                                   5-9
3    Write a code for prefix to postfix                                                 10-13
4    Write a code for prefix to infix                                                   14-17
5    Write a code for postfix to prefix                                                 18-21
6    Write a code for postfix to infix                                                  22-25
7    Convert decimal number into bineary number.                                        26-28
8    Reverse string using Stack                                                         29-30
9    Check the balance of parenthesis.                                                  31-33
10   Implement a Single linked list with the following operations                       34-41
11   Implement a double linked list with the following operations                       42-49
12   Write a program to perform following operations on single variable polynomials     50-57
     using singly linked list. A. Accept a polynomial, B. Display C. Addition of two
     polynomials
13   Write a program to perform following operations on two variable polynomials        58-63
     using singly linked list. A. Accept a polynomial, B. Display C. Addition of two
     polynomials
14   Write a program to perform following operations on single variable polynomials     64-72
     using double linked list. A. Accept a polynomial, B. Display C. Addition of two
     polynomials
15   Write a program to perform following operations on two variable polynomials        73-79
     using double linked list. A. Accept a polynomial, B. Display C. Addition of two
     polynomials
16   Write a program to perform following operations on student database using          80-86
     single linked list.
     A. Display all students information, B. Display information in reverse order, C.
     Insert new students record in between, at last and at start, D. Delete existing
     students record from its place.
17   Write a program to perform following operations on student database using          87-94
     double linked list.
     A. Display all students information, B. Display information in reverse order, C.
     Insert new students record in between, at last and at start, D. Delete existing
     students record from its place.
18   Write a program to perform following operations on student database using               95-102
     circular single linked list. A. Display all students information, B. Display
     information in reverse order, C. Insert new students record in between, at last
     and at start, D. Delete existing students record from its place.
19   Write a program to perform following operations on student database using               103-111
     circular double linked list. A. Display all students information, B. Display
     information in reverse order, C. Insert new students record in between, at last
     and at start, D. Delete existing students record from its place.
20   Write a program to accept six digit integer number and store it in circular double      112-117
     linked list (each digit in separate node) and perform addition and subtraction
     operation on it. Also consider carry
21   Write a program to accept six digit integer number and store it in circular single      118-123
     linked list (each digit in separate node) and perform addition and subtraction
     operation on it. Also consider carry.
22   Write a program to accept two sorted double linked lists and merge them in a            124-129
     single linked list in such a way that the resultant linked list will be a sorted one.
23   Write a program to accept two sorted single linked lists and merge them in a            130-134
     single linked list in such a way that the resultant linked list will be a sorted one.
24   Write a program to implement following operations using stack. A. Factorial of a        135-139
     given number B. Decimal to binary conversion
     Implement a stack using Single linked list
25   Write a program to implement following operations using stack. A. Factorial of a        140-144
     given number B. Decimal to binary conversion
     Implement a stack using Double linked list
26   Write a program to accept a string of parenthesis and check its validity using          145-148
     stack. Implement stack using double linked list
27   Write a program to implement circular queue using circular single linked list and       149-153
     perform Add, delete and display operations.
28    Write a program to implement Josephus problem using circular double linked             154-157
     list.
29   Write a program to implement Josephus problem using circular double linked              158-160
     list.
30   Write a program to implement double ended queue using double linked list and            161-167
     perform Add, delete and display operations.
31   Write a program to accept a string from user and store its each character in a          168-172
     separate node of circular single linked list and check whether the entered string
     is a palindrome or not.
32   Implenet Queue using array.                                                           173-176
33   Write a program to implement a circular queue and perform the following               177-181
     operations on it. Addq, Delq, Display entire queue.
34   Write a program to implement a double-ended queue where the user can                  182-189
     remove the element from both the front and rear ends of the queue.
35   Write a program to implement a circular double-ended queue where the user             190-196
     can add and remove the elements from both the front and rear ends of the
     queue.
36   write a program for a Bank simulation of its teller operations to see how waiting     197-203
     times would be affected by adding another teller.
37   write a program to keep track of patients as they enter a medical clinic, assigning   204-209
     patients to the doctor on a first-come, first-serve basis.
38   write a program to implement josephus problem.                                        210-214
39   Write a menu driven program to create a Binary Tree and perform following non- 215-221
     recursive operations on it.
     1. Preorder traversal, 2. Display mirror image of a tree without creating new
     tree, 3. Display height of a tree.
40   Write a menu driven program to create a Binary Tree and perform following non- 222-229
     recursive operations on it.
       1. Postorder Traversal, 2. Display a tree levelwise, 3. Display leaf nodes of a
     tree.
41   Write a menu driven program to create a Binary Tree and perform following non- 230-236
     recursive operations on it.
       1. Inorder Traversal, 2. Display mirror image of a tree by creating new tree, 3.
     Equality of two trees.
42   Write a menu driven program to create a Binary Tree and perform following non- 237-244
     recursive operations on it.
      1. Postorder Traversal, 2. Preorder Traversal, 3. Copy a tree.
43   Write a menu driven program to create a Binary Search Tree and perform                245-251
     following non-recursive operations on it.
       1. Preorder traversal, 2. Display mirror image of a tree without creating new
     tree, 3. Display height of a tree.
44    Write a menu driven program to create a Binary Search Tree and perform               252-260
     following non-recursive operations on it.
       1. Postorder Traversal, 2. Display a tree levelwise, 3. Display leaf nodes of a
     tree.
45   Write a menu driven program to create a Binary Search Tree and perform                261-268
     following non-recursive operations on it.
       1. Inorder Traversal, 2. Display mirror image of a tree by creating new tree, 3.
     Delete a node from a tree.
46   Write a menu driven program to create a Binary Search Tree and perform                 269-276
     following non-recursive operations on it.
      1. Postorder Traversal, 2. Preorder Traversal, 3. Inorder Traversal.
47   Write a menu driven program to create a Binary Search Tree and perform                 277-286
     following non-recursive operations on it.
     1. Copy a tree, 2. Equality of two trees, 3. Delete a node from a tree.
48   Write a menu driven program to create a Binary Search Tree and perform                 287-293
     following non-recursive operations on it.
     1. Insert a node in a tree, 2. Display the height of the tree, 3. Delete a node from
     a tree.
49   Right Threaded Binary Tree                                                             294-298
50   Full Threaded Binary Tree                                                              299-304
51   Write a C Program to implement Heap sort using Max heap in descending order            305-308
52   Write a C Program to implement Heap sort using Min heap in ascending order             309-312
53   Write a menu driven program to implement Inorder Threaded Binary tree and              313-319
     traverse it in Inorder, Preorder and Postorder way.(use inorder threads only)
54   Left Threaded Binary Tree                                                              320-324
Q1.Write a code for infix to postfix :-
  #include <stdio.h>
  #include <stdlib.h>
  #include <ctype.h>
  #include <string.h>
  #define MAX 100
  // Stack structure
  typedef struct {
     char items[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 c) {
     if (isFull(s)) {
        printf("Stack Overflow\n");
        return;
     }
     s->items[++s->top] = c;
}
// Function to pop an element from the stack
char pop(Stack *s) {
   if (isEmpty(s)) {
      printf("Stack Underflow\n");
      return ;
   }
   return s->items[s->top--];
}
// Function to get the top element of the stack
char peek(Stack *s) {
   if (isEmpty(s)) {
      return '\0';
   }
   return s->items[s->top];
}
// Function to determine the precedence of operators
int precedence(char op) {
   if (op == '+' || op == '-') return 1;
   if (op == '*' || op == '/') return 2;
   if (op == '^') return 3;
   return 0;
}
// Function to check if a character is an operator
int isOperator(char c) {
   return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
// Function to convert infix expression to postfix
void infixToPostfix(char *infix, char *postfix) {
   Stack s;
   initStack(&s);
   int i = 0, j = 0;
  char c;
  while (infix[i] != '\0') {
   c = infix[i];
    // If the character is an operand, add it to the postfix expression
    if (isalnum(c)) {
       postfix[j++] = c;
    }
    // If the character is '(', push it onto the stack
    else if (c == '(') {
       push(&s, c);
    }
    // If the character is ')', pop and append to postfix until '(' is
encountered
    else if (c == ')') {
       while (!isEmpty(&s) && peek(&s) != '(') {
          postfix[j++] = pop(&s);
       }
       pop(&s); // Remove the '(' from the stack
    }
    // If the character is an operator
    else if (isOperator(c)) {
       while (!isEmpty(&s) && precedence(peek(&s)) >= precedence(c)) {
          postfix[j++] = pop(&s);
       }
       push(&s, c);
    }
    i++;
  }
  // Pop all the remaining operators from the stack
  while (!isEmpty(&s)) {
     postfix[j++] = pop(&s);
  }
  postfix[j] = '\0'; // Null-terminate the postfix expression
}
// Main function
int main() {
   char infix[MAX], postfix[MAX];
    printf("Enter an infix expression: ");
    scanf("%s", infix);
    infixToPostfix(infix, postfix);
    printf("Postfix expression: %s\n", postfix);
    return 0;
}
Q2 Write a code for infix to prefix:-
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX 100
// Stack structure
typedef struct {
    char items[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 c) {
    if (isFull(s)) {
        printf("Stack Overflow\n");
        return;
    }
    s->items[++s->top] = c;
}
// Function to pop an element from the stack
char pop(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack Underflow\n");
        return '\0';
    }
    return s->items[s->top--];
}
// Function to get the top element of the stack
char peek(Stack *s) {
    if (isEmpty(s)) {
        return '\0';
    }
    return s->items[s->top];
}
// Function to determine the precedence of operators
int precedence(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/') return 2;
    if (op == '^') return 3;
    return 0;
}
// Function to check if a character is an operator
int isOperator(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
// Function to reverse a string
void reverse(char *exp) {
    int length = strlen(exp);
    for (int i = 0; i < length / 2; i++) {
        char temp = exp[i];
        exp[i] = exp[length - i - 1];
        exp[length - i - 1] = temp;
    }
}
// Function to convert infix expression to prefix expression
void infixToPrefix(char *infix, char *prefix) {
  Stack s;
  initStack(&s);
  reverse(infix);
  int j = 0;
  for (int i = 0; infix[i]; i++) {
     char c = infix[i];
    if (isalnum(c)) { // If the character is an operand, add it to the prefix
output
         prefix[j++] = c;
     } else if (c == ')') { // If the character is ')', push it onto the stack
         push(&s, c);
     } else if (c == '(') { // If the character is '(', pop and add to prefix until ')'
is found
         while (!isEmpty(&s) && peek(&s) != ')') {
             prefix[j++] = pop(&s);
         }
         pop(&s); // Remove ')'
     } else if (isOperator(c)) { // If the character is an operator
         while (!isEmpty(&s) && precedence(peek(&s)) > precedence(c)) {
             prefix[j++] = pop(&s);
         }
         push(&s, c);
     }
    }
    // Pop remaining operators from the stack
    while (!isEmpty(&s)) {
        prefix[j++] = pop(&s);
    }
    prefix[j] = '\0';
    reverse(prefix); // Reverse the result to get the correct prefix expression
    reverse(infix); // Optional: Restore the original infix expression
}
int main() {
    char infix[MAX], prefix[MAX];
    printf("Enter infix expression: ");
    scanf("%s", infix);
    infixToPrefix(infix, prefix);
    printf("Prefix expression: %s\n", prefix);
    return 0;
}
Q3 Write a code for prefix to postfix
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
// Stack structure
typedef struct {
    char items[MAX][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 *str) {
    if (isFull(s)) {
        printf("Stack Overflow\n");
        return;
    }
    strcpy(s->items[++s->top], str);
}
// Function to pop an element from the stack
char *pop(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack Underflow\n");
        return NULL;
    }
    return s->items[s->top--];
}
// Function to check if a character is an operator
int isOperator(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
// Function to reverse a string
void reverse(char *exp) {
    int length = strlen(exp);
    for (int i = 0; i < length / 2; i++) {
        char temp = exp[i];
        exp[i] = exp[length - i - 1];
        exp[length - i - 1] = temp;
    }
}
// Function to convert prefix to postfix
void prefixToPostfix(char *prefix) {
    Stack s;
    initStack(&s);
    reverse(prefix); // Reverse the prefix expression for easier processing
    for (int i = 0; i < strlen(prefix); i++) {
        // If character is an operand, push it to the stack
        if (isalnum(prefix[i])) {
            char operand[2] = {prefix[i], '\0'}; // Convert character to string
            push(&s, operand);
        }
    // If character is an operator, pop two operands and form a postfix
expression
        else if (isOperator(prefix[i])) {
            char op1[MAX], op2[MAX];
            strcpy(op1, pop(&s));
            strcpy(op2, pop(&s));
            // Form a new postfix string "op1 op2 operator"
            char temp[MAX];
            snprintf(temp, sizeof(temp), "%s%s%c", op1, op2, prefix[i]);
            // Push the resultant postfix expression back to stack
            push(&s, temp);
        }
    }
    // The final element of the stack is the postfix expression
    printf("Postfix Expression: %s\n", pop(&s));
}
// Main function to test the prefix to postfix conversion
int main() {
    char prefix[MAX];
    printf("Enter a prefix expression: ");
    scanf("%s", prefix);
    prefixToPostfix(prefix);
    return 0;
}
     Q4. Write a code for prefix to infix
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
// Stack structure
typedef struct {
    char items[MAX][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 *str) {
    if (isFull(s)) {
        printf("Stack Overflow\n");
        return;
    }
    strcpy(s->items[++s->top], str);
}
// Function to pop an element from the stack
char *pop(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack Underflow\n");
        return NULL;
    }
    return s->items[s->top--];
}
// Function to check if a character is an operator
int isOperator(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
// Function to reverse a string
void reverse(char *exp) {
    int length = strlen(exp);
    for (int i = 0; i < length / 2; i++) {
        char temp = exp[i];
        exp[i] = exp[length - i - 1];
        exp[length - i - 1] = temp;
    }
}
// Function to convert prefix to infix
void prefixToInfix(char *prefix) {
    Stack s;
    initStack(&s);
    reverse(prefix); // Reverse the prefix expression for easier processing
    for (int i = 0; i < strlen(prefix); i++) {
        // If character is an operand, push it to the stack
        if (isalnum(prefix[i])) {
            char operand[2] = {prefix[i], '\0'}; // Convert character to string
            push(&s, operand);
        }
    // If character is an operator, pop two operands and form an infix
expression
        else if (isOperator(prefix[i])) {
            char op1[MAX], op2[MAX];
            strcpy(op1, pop(&s));
            strcpy(op2, pop(&s));
            // Form a new infix string "(op1 operator op2)"
            char temp[MAX];
            snprintf(temp, sizeof(temp), "(%s %c %s)", op1, prefix[i], op2);
            // Push the resultant infix expression back to stack
            push(&s, temp);
        }
    }
    // The final element of the stack is the infix expression
    printf("Infix Expression: %s\n", pop(&s));
}
// Main function to test the prefix to infix conversion
int main() {
    char prefix[MAX];
    printf("Enter a prefix expression: ");
    scanf("%s", prefix);
    prefixToInfix(prefix);
    return 0;
}
Q5 Write a code for postfix to prefix
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
// Stack structure
typedef struct {
    char items[MAX][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 *str) {
    if (isFull(s)) {
        printf("Stack Overflow\n");
        return;
    }
    strcpy(s->items[++s->top], str);
}
// Function to pop an element from the stack
char *pop(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack Underflow\n");
        return NULL;
    }
    return s->items[s->top--];
}
// Function to check if a character is an operator
int isOperator(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
// Function to convert postfix to prefix
void postfixToPrefix(char *postfix) {
  Stack s;
  initStack(&s);
  for (int i = 0; i < strlen(postfix); i++) {
      // If character is an operand, push it to the stack
      if (isalnum(postfix[i])) {
          char operand[2] = {postfix[i], '\0'}; // Convert character to string
          push(&s, operand);
      }
    // If character is an operator, pop two operands and form a prefix
expression
      else if (isOperator(postfix[i])) {
          char op1[MAX], op2[MAX];
          strcpy(op2, pop(&s)); // Second operand
          strcpy(op1, pop(&s)); // First operand
          // Form a new prefix string "operator op1 op2"
          char temp[MAX];
          snprintf(temp, sizeof(temp), "%c%s%s", postfix[i], op1, op2);
          // Push the resultant prefix expression back to stack
          push(&s, temp);
      }
  }
    // The final element of the stack is the prefix expression
    printf("Prefix Expression: %s\n", pop(&s));
}
// Main function to test the postfix to prefix conversion
int main() {
    char postfix[MAX];
    printf("Enter a postfix expression: ");
    scanf("%s", postfix);
    postfixToPrefix(postfix);
    return 0;
}
Q6 Write a code for postfix to infix
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
// Stack structure
typedef struct {
    char items[MAX][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 *str) {
    if (isFull(s)) {
        printf("Stack Overflow\n");
        return;
    }
    strcpy(s->items[++s->top], str);
}
// Function to pop an element from the stack
char *pop(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack Underflow\n");
        return NULL;
    }
    return s->items[s->top--];
}
// Function to check if a character is an operator
int isOperator(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}
// Function to convert postfix to infix
void postfixToInfix(char *postfix) {
  Stack s;
  initStack(&s);
  for (int i = 0; i < strlen(postfix); i++) {
      // If character is an operand, push it to the stack
      if (isalnum(postfix[i])) {
          char operand[2] = {postfix[i], '\0'}; // Convert character to string
          push(&s, operand);
      }
    // If character is an operator, pop two operands and form an infix
expression
      else if (isOperator(postfix[i])) {
          char op2[MAX], op1[MAX];
          strcpy(op2, pop(&s)); // Second operand
          strcpy(op1, pop(&s)); // First operand
          // Form a new infix string "(op1 operator op2)"
          char temp[MAX];
          snprintf(temp, sizeof(temp), "(%s %c %s)", op1, postfix[i], op2);
          // Push the resultant infix expression back to stack
          push(&s, temp);
      }
  }
    // The final element of the stack is the infix expression
    printf("Infix Expression: %s\n", pop(&s));
}
// Main function to test the postfix to infix conversion
int main() {
    char postfix[MAX];
    printf("Enter a postfix expression: ");
    scanf("%s", postfix);
    postfixToInfix(postfix);
    return 0;
}
Q7 Converst decimal number into bineary number.
#include <stdio.h>
#include <stdlib.h>
#define MAX 32 // Maximum stack size for binary digits
// Define stack structure using typedef
typedef struct {
    int items[MAX];
    int top;
} Stack;
// Function to initialize stack
void initStack(Stack* s) {
    s->top = -1;
}
// Function to check if the stack is full
int isFull(Stack* s) {
    return s->top == MAX - 1;
}
// Function to check if the stack is empty
int isEmpty(Stack* s) {
    return s->top == -1;
}
// Function to push an element to the stack
void push(Stack* s, int value) {
    if (isFull(s)) {
        printf("Stack Overflow\n");
    } else {
        s->items[++(s->top)] = value;
    }
}
// Function to pop an element from the stack
int pop(Stack* s) {
    if (isEmpty(s)) {
        printf("Stack Underflow\n");
        return -1;
    } else {
        return s->items[(s->top)--];
    }
}
// Function to convert decimal to binary using stack
void decimalToBinary(int decimal) {
    Stack stack;
    initStack(&stack);
  // Convert decimal to binary by dividing by 2 and pushing remainders
onto the stack
    while (decimal > 0) {
        int remainder = decimal % 2;
        push(&stack, remainder);
        decimal /= 2;
    }
    // Pop all elements to get the binary number in correct order
    printf("Binary representation: ");
    while (!isEmpty(&stack)) {
        printf("%d", pop(&stack));
    }
    printf("\n");
}
int main() {
    int decimal;
    printf("Enter a decimal number: ");
    scanf("%d", &decimal);
    decimalToBinary(decimal);
    return 0;
}
Q8 Reverse string using Stack
#include <stdio.h>
#include <string.h>
char stack[20];
int top = -1;
void push(char);
char pop();
int main()
{
char str[20], ch;
int l, i;
printf("Enter string: ");
scanf("%s", str);
l = strlen(str);
for (i = 0; i < l; i++)
push(str[i]);
printf("Reversed string: ");
for (i = 0; i < l; i++)
{
ch = pop();
printf("%c", ch);
}
return 0;
}
void push(char c)
{
if (top < 19)
{ // Ensure we don't exceed the stack size
top++;
stack[top] = c;
}
else
{
printf("Stack overflow\n");
}
}
char pop()
{
if (top >= 0)
{
char c = stack[top];
top--;
return c;
} else
{
printf("Stack underflow\n");
return 0;
}
}
Q9 Check the balance of parenthesis.
#include <stdio.h>
#include <string.h>
#define MAX 1000
char stack[MAX];
int top = -1;
// Function to push an element to the stack
void push(char item)
{
if (top < MAX - 1)
{
stack[++top] = item;
}
}
// Function to pop an element from the stack
char pop()
{
if (top >= 0)
{
return stack[top--];
}
return '\0'; // Return null character if stack is empty
}
// Function to check if the given character is an opening parenthesis
int isOpening(char ch)
{
return ch == '(' || ch == '{' ||ch == '[';
}
// Function to check if the given character is a closing parenthesis
int isClosing(char ch)
{
return ch == ')' || ch == '}' ||
ch == ']';
}
// Function to check if the opening and closing parentheses match
int isMatching(char open, char close)
{
return (open == '(' && close ==')') ||(open == '{' && close == '}') ||(open ==
'[' && close == ']');
}
// Function to check if the parentheses are balanced
int isBalanced(char* expr)
{
for (int i = 0; i <strlen(expr); i++)
{
char ch = expr[i];
if (isOpening(ch))
{
push(ch);
}
else if (isClosing(ch))
{
if (top == -1 ||!isMatching(pop(), ch))
{
return 0;
}
}
}
return top == -1;
}
int main()
{
char expr[MAX];
printf("Enter an expression: ");
scanf("%s", expr);
if (isBalanced(expr))
{
printf("The parentheses are balanced.\n");
}
else
{
printf("The parentheses are not balanced.\n");
}
return 0;
}
      Q 10 Implement a Single linked list with the following
      operations:
      1. Insert node at the beginning
      2. Insert node at end
      3. Insert node in middle
      4. delete node from end
      5. delete node from start
      6. delete node from mid
#include <stdio.h>
#include <stdlib.h>
// Node structure
struct Node {
     int data;
     struct Node *prev;
     struct Node *next;
};
// Function to create a new node
struct Node *createNode(int data) {
     struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
     newNode->data = data;
     newNode->prev = NULL;
     newNode->next = NULL;
     return newNode;
}
// Insert node at the beginning
void insertAtBeginning(struct Node **head, int data) {
    struct Node *newNode = createNode(data);
    if (*head == NULL) {
        *head = newNode;
    } else {
        newNode->next = *head;
        (*head)->prev = newNode;
        *head = newNode;
    }
}
// Insert node at the end
void insertAtEnd(struct Node **head, int data) {
    struct Node *newNode = createNode(data);
    if (*head == NULL) {
        *head = newNode;
    } else {
        struct Node *temp = *head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = newNode;
        newNode->prev = temp;
    }
}
// Insert node in the middle (after a given node)
void insertInMiddle(struct Node *prevNode, int data) {
    if (prevNode == NULL) {
        printf("Previous node cannot be NULL\n");
        return;
    }
    struct Node *newNode = createNode(data);
    newNode->next = prevNode->next;
    newNode->prev = prevNode;
    if (prevNode->next != NULL) {
        prevNode->next->prev = newNode;
    }
    prevNode->next = newNode;
}
// Delete node from the start
void deleteFromStart(struct Node **head) {
    if (*head == NULL) {
        printf("List is empty\n");
        return;
    }
    struct Node *temp = *head;
    *head = (*head)->next;
    if (*head != NULL) {
        (*head)->prev = NULL;
    }
    free(temp);
}
// Delete node from the end
void deleteFromEnd(struct Node **head) {
    if (*head == NULL) {
        printf("List is empty\n");
        return;
    }
    struct Node *temp = *head;
    if (temp->next == NULL) { // Only one node in the list
        free(temp);
        *head = NULL;
        return;
    }
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->prev->next = NULL;
    free(temp);
}
// Delete node from the middle (after a given node)
void deleteFromMiddle(struct Node *node) {
    if (node == NULL || node->next == NULL) {
        printf("Invalid operation\n");
        return;
    }
    struct Node *temp = node->next;
    node->next = temp->next;
    if (temp->next != NULL) {
        temp->next->prev = node;
    }
    free(temp);
}
// Display the list
void displayList(struct Node *head) {
    struct Node *temp = head;
    printf("Doubly Linked List: ");
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}
int main() {
    struct Node *head = NULL;
int choice, value, pos;
struct Node *temp = NULL;
while (1) {
  printf("\nMenu:\n");
  printf("1. Insert at Beginning\n");
  printf("2. Insert at End\n");
  printf("3. Insert in Middle\n");
  printf("4. Delete from Start\n");
  printf("5. Delete from End\n");
  printf("6. Delete from Middle\n");
  printf("7. Display List\n");
  printf("8. Exit\n");
  printf("Enter your choice: ");
  scanf("%d", &choice);
  switch (choice) {
    case 1:
       printf("Enter value to insert at beginning: ");
       scanf("%d", &value);
       insertAtBeginning(&head, value);
       break;
    case 2:
       printf("Enter value to insert at end: ");
       scanf("%d", &value);
       insertAtEnd(&head, value);
       break;
    case 3:
  printf("Enter value to insert in middle: ");
  scanf("%d", &value);
  printf("Enter the position after which to insert: ");
  scanf("%d", &pos);
  temp = head;
  for (int i = 1; i < pos && temp != NULL; i++) {
      temp = temp->next;
  }
  if (temp != NULL) {
      insertInMiddle(temp, value);
  } else {
      printf("Invalid position!\n");
  }
  break;
case 4:
  deleteFromStart(&head);
  break;
case 5:
  deleteFromEnd(&head);
  break;
case 6:
  printf("Enter the position after which to delete: ");
  scanf("%d", &pos);
  temp = head;
  for (int i = 1; i < pos && temp != NULL; i++) {
      temp = temp->next;
              }
              if (temp != NULL && temp->next != NULL) {
                  deleteFromMiddle(temp);
              } else {
                  printf("Invalid position!\n");
              }
              break;
            case 7:
              displayList(head);
              break;
            case 8:
              exit(0);
              break;
            default:
              printf("Invalid choice! Please try again.\n");
              break;
        }
    }
    return 0;
}
     Q 11 Implement a double linked list with the following
     operations:
     1. Insert node at the beginning
     2. Insert node at end
     3. Insert node in middle
     4. delete node from end
     5. delete node from start
     6. delete node from mid
#include <stdio.h>
#include <stdlib.h>
// Node structure
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
// Function to create a new node
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
// Insert node at the beginning
void insertAtBeginning(struct Node** head, int data) {
struct Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
} else {
newNode->next = *head;
(*head)->prev = newNode;
*head = newNode;
}
}
// Insert node at the end
void insertAtEnd(struct Node** head, int data) {
struct Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
} else {
struct Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
}
// Insert node in the middle (after a given node)
void insertInMiddle(struct Node* prevNode, int data) {
if (prevNode == NULL) {
printf("Previous node cannot be NULL\n");
return;
}
struct Node* newNode = createNode(data);
newNode->next = prevNode->next;
newNode->prev = prevNode;
if (prevNode->next != NULL) {
prevNode->next->prev = newNode;
}
prevNode->next = newNode;
}
// Delete node from the start
void deleteFromStart(struct Node** head) {
if (*head == NULL) {
printf("List is empty\n");
return;
}
struct Node* temp = *head;
*head = (*head)->next;
if (*head != NULL) {
(*head)->prev = NULL;
}
free(temp);
}
// Delete node from the end
void deleteFromEnd(struct Node** head) {
if (*head == NULL) {
printf("List is empty\n");
return;
}
struct Node* temp = *head;
if (temp->next == NULL) { // Only one node in the list
free(temp);
*head = NULL;
return;
}
while (temp->next != NULL) {
temp = temp->next;
}
temp->prev->next = NULL;
free(temp);
}
// Delete node from the middle (after a given node)
void deleteFromMiddle(struct Node* node) {
if (node == NULL || node->next == NULL) {
printf("Invalid operation\n");
return;
}
struct Node* temp = node->next;
node->next = temp->next;
if (temp->next != NULL) {
temp->next->prev = node;
}
free(temp);
}
// Display the list
void displayList(struct Node* head) {
struct Node* temp = head;
printf("Doubly Linked List: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
struct Node* head = NULL;
int choice, value, pos;
struct Node* temp = NULL;
while (1) {
printf("\nMenu:\n");
printf("1. Insert at Beginning\n");
printf("2. Insert at End\n");
printf("3. Insert in Middle\n");
printf("4. Delete from Start\n");
printf("5. Delete from End\n");
printf("6. Delete from Middle\n");
printf("7. Display List\n");
printf("8. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter value to insert at beginning: ");
scanf("%d", &value);
insertAtBeginning(&head, value);
break;
case 2:
printf("Enter value to insert at end: ");
scanf("%d", &value);
insertAtEnd(&head, value);
break;
case 3:
printf("Enter value to insert in middle: ");
scanf("%d", &value);
printf("Enter the position after which to insert: ");
scanf("%d", &pos);
temp = head;
for (int i = 1; i < pos && temp != NULL; i++) {
temp = temp->next;
}
if (temp != NULL) {
insertInMiddle(temp, value);
} else {
printf("Invalid position!\n");
}
break;
case 4:
deleteFromStart(&head);
break;
case 5:
deleteFromEnd(&head);
break;
case 6:
printf("Enter the position after which to delete: ");
scanf("%d", &pos);
temp = head;
for (int i = 1; i < pos && temp != NULL; i++) {
temp = temp->next;
}
if (temp != NULL && temp->next != NULL) {
deleteFromMiddle(temp);
} else {
printf("Invalid position!\n");
}
break;
case 7:
displayList(head);
break;
case 8:
exit(0);
break;
default:
printf("Invalid choice! Please try again.\n");
break;
}
}
return 0;
}
Q13 Write a program to perform following operations on single variable
polynomials using singly linked list. A. Accept a polynomial, B. Display C.
Addition of two polynomials
#include <stdio.h>
#include <stdlib.h>
// Node structure to represent each term of the polynomial
struct Node {
     int coeff; // Coefficient of the term
     int exp; // Exponent of the term
     struct Node *next; // Pointer to the next term
};
// Function to create a new node
struct Node *createNode(int coeff, int exp) {
     struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
     newNode->coeff = coeff;
     newNode->exp = exp;
     newNode->next = NULL;
     return newNode;
// Function to accept a polynomial
void acceptPolynomial(struct Node **head) {
    int n, coeff, exp;
    printf("Enter the number of terms in the polynomial: ");
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        printf("Enter coefficient and exponent for term %d: ", i + 1);
        scanf("%d %d", &coeff, &exp);
        struct Node *newNode = createNode(coeff, exp);
        if (*head == NULL || (*head)->exp < exp) {
            newNode->next = *head;
            *head = newNode;
        } else {
            struct Node *temp = *head;
            while (temp->next != NULL && temp->next->exp > exp) {
                temp = temp->next;
            newNode->next = temp->next;
            temp->next = newNode;
}
// Function to display the polynomial
void displayPolynomial(struct Node *head) {
    struct Node *temp = head;
    if (temp == NULL) {
        printf("Polynomial is empty.\n");
        return;
    while (temp != NULL) {
        if (temp->coeff > 0 && temp != head) {
            printf(" + ");
        printf("%dx^%d", temp->coeff, temp->exp);
        temp = temp->next;
    printf("\n");
// Function to add two polynomials
struct Node *addPolynomials(struct Node *poly1, struct Node *poly2) {
    struct Node *result = NULL, *temp = NULL;
    while (poly1 != NULL && poly2 != NULL) {
        if (poly1->exp > poly2->exp) {
  // Add term from poly1
  if (result == NULL) {
      result = createNode(poly1->coeff, poly1->exp);
      temp = result;
  } else {
      temp->next = createNode(poly1->coeff, poly1->exp);
      temp = temp->next;
  poly1 = poly1->next;
} else if (poly1->exp < poly2->exp) {
  // Add term from poly2
  if (result == NULL) {
      result = createNode(poly2->coeff, poly2->exp);
      temp = result;
  } else {
      temp->next = createNode(poly2->coeff, poly2->exp);
      temp = temp->next;
  poly2 = poly2->next;
} else {
  // Add terms from both polynomials with the same exponent
  int coeffSum = poly1->coeff + poly2->coeff;
  if (coeffSum != 0) {
      if (result == NULL) {
                result = createNode(coeffSum, poly1->exp);
                temp = result;
            } else {
                temp->next = createNode(coeffSum, poly1->exp);
                temp = temp->next;
        poly1 = poly1->next;
        poly2 = poly2->next;
// Add remaining terms of poly1
while (poly1 != NULL) {
    if (result == NULL) {
        result = createNode(poly1->coeff, poly1->exp);
        temp = result;
    } else {
        temp->next = createNode(poly1->coeff, poly1->exp);
        temp = temp->next;
    poly1 = poly1->next;
}
    // Add remaining terms of poly2
    while (poly2 != NULL) {
        if (result == NULL) {
            result = createNode(poly2->coeff, poly2->exp);
            temp = result;
        } else {
            temp->next = createNode(poly2->coeff, poly2->exp);
            temp = temp->next;
        poly2 = poly2->next;
    return result;
int main() {
    struct Node *poly1 = NULL, *poly2 = NULL, *result = NULL;
    int choice;
    while (1) {
        printf("\nMenu:\n");
        printf("1. Accept Polynomial 1\n");
        printf("2. Accept Polynomial 2\n");
        printf("3. Display Polynomial 1\n");
printf("4. Display Polynomial 2\n");
printf("5. Add Polynomials\n");
printf("6. Display Resultant Polynomial\n");
printf("7. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
  case 1:
     acceptPolynomial(&poly1);
     break;
  case 2:
     acceptPolynomial(&poly2);
     break;
  case 3:
     printf("Polynomial 1: ");
     displayPolynomial(poly1);
     break;
  case 4:
     printf("Polynomial 2: ");
     displayPolynomial(poly2);
     break;
  case 5:
     result = addPolynomials(poly1, poly2);
              printf("Polynomials added.\n");
              break;
            case 6:
              printf("Resultant Polynomial: ");
              displayPolynomial(result);
              break;
            case 7:
              exit(0);
            default:
              printf("Invalid choice! Try again.\n");
    return 0;
}
Q14 Write a program to perform following operations on two variable
polynomials using singly linked list. A. Accept a polynomial, B. Display C.
Addition of two polynomials
#include <stdio.h>
#include <stdlib.h>
// Structure to represent a term of a polynomial
struct Term {
     int coeff;    // Coefficient of the term
     int xPower;    // Power of x
     int yPower;    // Power of y
     struct Term *next; // Pointer to the next term
};
// Function to create a new term
struct Term* createTerm(int coeff, int xPower, int yPower) {
     struct Term newTerm = (struct Term)malloc(sizeof(struct Term));
     newTerm->coeff = coeff;
     newTerm->xPower = xPower;
     newTerm->yPower = yPower;
     newTerm->next = NULL;
     return newTerm;
// Function to accept a polynomial
void acceptPolynomial(struct Term **head) {
  int coeff, xPower, yPower;
  struct Term *temp, *last = NULL;
  printf("Enter terms of the polynomial in the format 'coefficient xPower
yPower'.\n");
  printf("Enter '0 0 0' when you are done entering terms.\n");
  while (1) {
      printf("Enter term: ");
      scanf("%d %d %d", &coeff, &xPower, &yPower);
      if (coeff == 0 && xPower == 0 && yPower == 0) {
          printf("Polynomial entry completed.\n");
          break;
      temp = createTerm(coeff, xPower, yPower);
      if (*head == NULL) {
          *head = temp;
      } else {
          last->next = temp;
      last = temp;
  }
}
// Function to display a polynomial
void displayPolynomial(struct Term *head) {
    struct Term *temp = head;
    if (temp == NULL) {
        printf("Polynomial is empty.\n");
        return;
    while (temp != NULL) {
        if (temp->coeff != 0) {
     printf("%d*x^%d*y^%d", temp->coeff, temp->xPower, temp-
>yPower);
            if (temp->next != NULL && temp->next->coeff > 0)
              printf(" + ");
        temp = temp->next;
    printf("\n");
// Function to add two polynomials
struct Term* addPolynomials(struct Term *poly1, struct Term *poly2) {
    struct Term *result = NULL, *last = NULL;
  printf("\nAdding the two polynomials...\n");
  while (poly1 != NULL || poly2 != NULL) {
    struct Term *temp = NULL;
    if (poly1 != NULL && (poly2 == NULL || poly1->xPower > poly2-
>xPower ||
     (poly1->xPower == poly2->xPower && poly1->yPower > poly2-
>yPower))) {
        temp = createTerm(poly1->coeff, poly1->xPower, poly1->yPower);
        poly1 = poly1->next;
    } else if (poly2 != NULL && (poly1 == NULL || poly2->xPower > poly1-
>xPower ||
     (poly1->xPower == poly2->xPower && poly2->yPower > poly1-
>yPower))) {
        temp = createTerm(poly2->coeff, poly2->xPower, poly2->yPower);
        poly2 = poly2->next;
    } else {
       temp = createTerm(poly1->coeff + poly2->coeff, poly1->xPower,
poly1->yPower);
        poly1 = poly1->next;
        poly2 = poly2->next;
    if (result == NULL) {
            result = temp;
        } else {
            last->next = temp;
        last = temp;
    return result;
int main() {
    struct Term *poly1 = NULL, *poly2 = NULL, *result = NULL;
    printf("### Polynomial Operations Using Singly Linked List ###\n\n");
    // Accept first polynomial
    printf("Enter the first polynomial:\n");
    acceptPolynomial(&poly1);
    // Accept second polynomial
    printf("\nEnter the second polynomial:\n");
    acceptPolynomial(&poly2);
    // Display the polynomials
    printf("\nFirst Polynomial: ");
    displayPolynomial(poly1);
    printf("Second Polynomial: ");
    displayPolynomial(poly2);
    // Add the two polynomials
    result = addPolynomials(poly1, poly2);
    // Display the result
    printf("\nSum of Polynomials: ");
    displayPolynomial(result);
    printf("\nOperation completed. Thank you!\n");
    return 0;
}
Q 15 Write a program to perform following operations on single variable
polynomials using double linked list. A. Accept a polynomial, B. Display
C. Addition of two polynomials
#include <stdio.h>
#include <stdlib.h>
// Node structure to represent each term of the polynomial
struct Node {
     int coeff; // Coefficient of the term
     int exp; // Exponent of the term
     struct Node *prev; // Pointer to the previous term
     struct Node *next; // Pointer to the next term
};
// Function to create a new node
struct Node* createNode(int coeff, int exp) {
     struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
     newNode->coeff = coeff;
     newNode->exp = exp;
     newNode->prev = NULL;
     newNode->next = NULL;
     return newNode;
// Function to accept a polynomial
void acceptPolynomial(struct Node** head) {
  int n, coeff, exp;
  printf("Enter the number of terms in the polynomial: ");
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    printf("Enter coefficient and exponent for term %d: ", i + 1);
    scanf("%d %d", &coeff, &exp);
    struct Node* newNode = createNode(coeff, exp);
    // Insert the new node in the sorted order (descending by exponent)
    if (*head == NULL || (*head)->exp < exp) {
       newNode->next = *head;
       if (*head != NULL) {
           (*head)->prev = newNode;
       *head = newNode;
    } else {
       struct Node* temp = *head;
       while (temp->next != NULL && temp->next->exp > exp) {
           temp = temp->next;
       newNode->next = temp->next;
            if (temp->next != NULL) {
                temp->next->prev = newNode;
            temp->next = newNode;
            newNode->prev = temp;
// Function to display the polynomial
void displayPolynomial(struct Node* head) {
    struct Node* temp = head;
    if (temp == NULL) {
        printf("Polynomial is empty.\n");
        return;
    while (temp != NULL) {
        if (temp->coeff > 0 && temp != head) {
            printf(" + ");
        printf("%dx^%d", temp->coeff, temp->exp);
        temp = temp->next;
    }
    printf("\n");
// Function to add two polynomials
struct Node* addPolynomials(struct Node* poly1, struct Node* poly2) {
    struct Node* result = NULL, *temp = NULL;
    while (poly1 != NULL && poly2 != NULL) {
      if (poly1->exp > poly2->exp) {
         // Add term from poly1
         if (result == NULL) {
             result = createNode(poly1->coeff, poly1->exp);
             temp = result;
         } else {
             temp->next = createNode(poly1->coeff, poly1->exp);
             temp->next->prev = temp;
             temp = temp->next;
         poly1 = poly1->next;
      } else if (poly1->exp < poly2->exp) {
         // Add term from poly2
         if (result == NULL) {
             result = createNode(poly2->coeff, poly2->exp);
             temp = result;
        } else {
            temp->next = createNode(poly2->coeff, poly2->exp);
            temp->next->prev = temp;
            temp = temp->next;
        poly2 = poly2->next;
    } else {
        // Add terms from both polynomials with the same exponent
        int coeffSum = poly1->coeff + poly2->coeff;
        if (coeffSum != 0) {
            if (result == NULL) {
                result = createNode(coeffSum, poly1->exp);
                temp = result;
            } else {
                temp->next = createNode(coeffSum, poly1->exp);
                temp->next->prev = temp;
                temp = temp->next;
        poly1 = poly1->next;
        poly2 = poly2->next;
}
// Add remaining terms of poly1
while (poly1 != NULL) {
    if (result == NULL) {
        result = createNode(poly1->coeff, poly1->exp);
        temp = result;
    } else {
        temp->next = createNode(poly1->coeff, poly1->exp);
        temp->next->prev = temp;
        temp = temp->next;
    poly1 = poly1->next;
// Add remaining terms of poly2
while (poly2 != NULL) {
    if (result == NULL) {
        result = createNode(poly2->coeff, poly2->exp);
        temp = result;
    } else {
        temp->next = createNode(poly2->coeff, poly2->exp);
        temp->next->prev = temp;
        temp = temp->next;
    poly2 = poly2->next;
    }
    return result;
int main() {
    struct Node* poly1 = NULL, *poly2 = NULL, *result = NULL;
    int choice;
    while (1) {
        printf("\nMenu:\n");
        printf("1. Accept Polynomial 1\n");
        printf("2. Accept Polynomial 2\n");
        printf("3. Display Polynomial 1\n");
        printf("4. Display Polynomial 2\n");
        printf("5. Add Polynomials\n");
        printf("6. Display Resultant Polynomial\n");
        printf("7. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
          case 1:
             acceptPolynomial(&poly1);
  break;
case 2:
  acceptPolynomial(&poly2);
  break;
case 3:
  printf("Polynomial 1: ");
  displayPolynomial(poly1);
  break;
case 4:
  printf("Polynomial 2: ");
  displayPolynomial(poly2);
  break;
case 5:
  result = addPolynomials(poly1, poly2);
  printf("Polynomials added.\n");
  break;
case 6:
  printf("Resultant Polynomial: ");
  displayPolynomial(result);
  break;
case 7:
  exit(0);
default:
  printf("Invalid choice! Try again.\n");
        }
    return 0;
}
Q16 Write a program to perform following operations on two variable
polynomials using double linked list. A. Accept a polynomial, B. Display
C. Addition of two polynomials
#include <stdio.h>
#include <stdlib.h>
// Structure to represent a term in the polynomial
struct Term {
     int coefficient;
     int xPower;
     int yPower;
     struct Term *prev;
     struct Term *next;
};
// Function to create a new term node
struct Term* createTerm(int coefficient, int xPower, int yPower) {
     struct Term* newTerm = (struct Term*) malloc(sizeof(struct Term));
     newTerm->coefficient = coefficient;
     newTerm->xPower = xPower;
     newTerm->yPower = yPower;
     newTerm->prev = NULL;
     newTerm->next = NULL;
     return newTerm;
}
// Function to accept a polynomial
void acceptPolynomial(struct Term** head) {
    int numTerms, coef, xPow, yPow;
    printf("Enter number of terms in the polynomial: ");
    scanf("%d", &numTerms);
    struct Term* tail = NULL;
    for (int i = 0; i < numTerms; i++) {
        printf("Enter coefficient, x power, and y power for term %d: ", i + 1);
        scanf("%d %d %d", &coef, &xPow, &yPow);
        struct Term* newTerm = createTerm(coef, xPow, yPow);
        if (*head == NULL) {
            *head = newTerm;
            tail = *head;
        } else {
            tail->next = newTerm;
            newTerm->prev = tail;
            tail = newTerm;
}
// Function to display the polynomial
void displayPolynomial(struct Term* head) {
    if (head == NULL) {
        printf("Polynomial is empty!\n");
        return;
    struct Term* temp = head;
    while (temp != NULL) {
    printf("%d*x^%d*y^%d", temp->coefficient, temp->xPower, temp-
>yPower);
        if (temp->next != NULL) {
            printf(" + ");
        temp = temp->next;
    printf("\n");
// Function to add two polynomials
struct Term* addPolynomials(struct Term* poly1, struct Term* poly2) {
    struct Term* result = NULL;
    struct Term* tail = NULL;
  while (poly1 != NULL && poly2 != NULL) {
    if (poly1->xPower == poly2->xPower && poly1->yPower == poly2-
>yPower) {
      int coef = poly1->coefficient + poly2->coefficient;
      if (coef != 0) {
        struct Term* newTerm = createTerm(coef, poly1->xPower,
poly1->yPower);
          if (result == NULL) {
              result = newTerm;
              tail = result;
          } else {
              tail->next = newTerm;
              newTerm->prev = tail;
              tail = newTerm;
      poly1 = poly1->next;
      poly2 = poly2->next;
    } else if (poly1->xPower > poly2->xPower || (poly1->xPower == poly2-
>xPower && poly1->yPower > poly2->yPower)) {
     struct Term* newTerm = createTerm(poly1->coefficient, poly1-
>xPower, poly1->yPower);
      if (result == NULL) {
          result = newTerm;
          tail = result;
      } else {
              tail->next = newTerm;
              newTerm->prev = tail;
              tail = newTerm;
          poly1 = poly1->next;
      } else {
     struct Term* newTerm = createTerm(poly2->coefficient, poly2-
>xPower, poly2->yPower);
          if (result == NULL) {
              result = newTerm;
              tail = result;
          } else {
              tail->next = newTerm;
              newTerm->prev = tail;
              tail = newTerm;
          poly2 = poly2->next;
  while (poly1 != NULL) {
    struct Term* newTerm = createTerm(poly1->coefficient, poly1-
>xPower, poly1->yPower);
      if (result == NULL) {
          result = newTerm;
            tail = result;
        } else {
            tail->next = newTerm;
            newTerm->prev = tail;
            tail = newTerm;
        poly1 = poly1->next;
    while (poly2 != NULL) {
    struct Term* newTerm = createTerm(poly2->coefficient, poly2-
>xPower, poly2->yPower);
        if (result == NULL) {
            result = newTerm;
            tail = result;
        } else {
            tail->next = newTerm;
            newTerm->prev = tail;
            tail = newTerm;
        poly2 = poly2->next;
    return result;
}
int main() {
    struct Term *poly1 = NULL, *poly2 = NULL, *result = NULL;
    printf("Enter the first polynomial:\n");
    acceptPolynomial(&poly1);
    printf("Enter the second polynomial:\n");
    acceptPolynomial(&poly2);
    printf("First Polynomial: ");
    displayPolynomial(poly1);
    printf("Second Polynomial: ");
    displayPolynomial(poly2);
    result = addPolynomials(poly1, poly2);
    printf("Sum of the polynomials: ");
    displayPolynomial(result);
    return 0;
}
Q 17 Write a program to perform following operations on student
database using single linked list.
A. Display all students information, B. Display information in reverse
order, C. Insert new students record in between, at last and at start, D.
Delete existing students record from its place.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
     int rollNumber;
     char name[50];
     struct Student* next;
};
struct Student* head = NULL;
// Function to create a new student node
struct Student* createStudent(int rollNumber, char name[]) {
  struct Student* newStudent = (struct Student*)malloc(sizeof(struct
Student));
     newStudent->rollNumber = rollNumber;
     strcpy(newStudent->name, name);
     newStudent->next = NULL;
     return newStudent;
}
// A. Display all students' information
void displayStudents() {
    struct Student* temp = head;
    printf("\nStudent List:\n");
    while (temp != NULL) {
   printf("Roll Number: %d, Name: %s\n", temp->rollNumber, temp-
>name);
        temp = temp->next;
// B. Display students' information in reverse order (using recursion)
void displayReverse(struct Student* node) {
    if (node == NULL) return;
    displayReverse(node->next);
  printf("Roll Number: %d, Name: %s\n", node->rollNumber, node-
>name);
// C. Insert new student record at the start
void insertAtStart(int rollNumber, char name[]) {
    struct Student* newStudent = createStudent(rollNumber, name);
    newStudent->next = head;
    head = newStudent;
// C. Insert new student record at the end
void insertAtEnd(int rollNumber, char name[]) {
    struct Student* newStudent = createStudent(rollNumber, name);
    if (head == NULL) {
        head = newStudent;
    } else {
        struct Student* temp = head;
        while (temp->next != NULL) {
            temp = temp->next;
        temp->next = newStudent;
// C. Insert new student record in between (after a given roll number)
void insertInBetween(int rollNumber, char name[], int afterRoll) {
    struct Student* temp = head;
    while (temp != NULL && temp->rollNumber != afterRoll) {
        temp = temp->next;
    if (temp != NULL) {
        struct Student* newStudent = createStudent(rollNumber, name);
        newStudent->next = temp->next;
        temp->next = newStudent;
    } else {
        printf("Student with roll number %d not found.\n", afterRoll);
// D. Delete an existing student record by roll number
void deleteStudent(int rollNumber) {
    struct Student *temp = head, *prev = NULL;
    if (temp != NULL && temp->rollNumber == rollNumber) {
        head = temp->next;
        free(temp);
        printf("Student with roll number %d deleted.\n", rollNumber);
        return;
    while (temp != NULL && temp->rollNumber != rollNumber) {
        prev = temp;
        temp = temp->next;
    if (temp == NULL) {
        printf("Student with roll number %d not found.\n", rollNumber);
        return;
    }
    prev->next = temp->next;
    free(temp);
    printf("Student with roll number %d deleted.\n", rollNumber);
// Main function
int main() {
    int choice, rollNumber, afterRoll;
    char name[50];
    while (1) {
        printf("\nMenu:\n");
        printf("1. Display all students\n");
        printf("2. Display students in reverse order\n");
        printf("3. Insert student at start\n");
        printf("4. Insert student at end\n");
        printf("5. Insert student in between\n");
        printf("6. Delete student\n");
        printf("7. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
case 1:
  displayStudents();
  break;
case 2:
  printf("\nStudents in Reverse Order:\n");
  displayReverse(head);
  break;
case 3:
  printf("Enter Roll Number and Name: ");
  scanf("%d", &rollNumber);
  getchar(); // to consume newline
  fgets(name, sizeof(name), stdin);
  name[strcspn(name, "\n")] = 0; // Remove newline character
  insertAtStart(rollNumber, name);
  break;
case 4:
  printf("Enter Roll Number and Name: ");
  scanf("%d", &rollNumber);
  getchar();
  fgets(name, sizeof(name), stdin);
  name[strcspn(name, "\n")] = 0;
  insertAtEnd(rollNumber, name);
  break;
case 5:
              printf("Enter Roll Number and Name to Insert: ");
              scanf("%d", &rollNumber);
              getchar();
              fgets(name, sizeof(name), stdin);
              name[strcspn(name, "\n")] = 0;
              printf("Enter Roll Number after which to insert: ");
              scanf("%d", &afterRoll);
              insertInBetween(rollNumber, name, afterRoll);
              break;
            case 6:
              printf("Enter Roll Number to Delete: ");
              scanf("%d", &rollNumber);
              deleteStudent(rollNumber);
              break;
            case 7:
              printf("Exiting...\n");
              exit(0);
            default:
              printf("Invalid choice! Please try again.\n");
    return 0;
}
Q 18 Write a program to perform following operations on student
database using double linked list.
A. Display all students information, B. Display information in reverse
order, C. Insert new students record in between, at last and at start, D.
Delete existing students record from its place.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
     int rollNumber;
     char name[50];
     struct Student* prev;
     struct Student* next;
};
struct Student* head = NULL;
// Function to create a new student node
struct Student* createStudent(int rollNumber, char name[]) {
  struct Student* newStudent = (struct Student*)malloc(sizeof(struct
Student));
     newStudent->rollNumber = rollNumber;
     strcpy(newStudent->name, name);
     newStudent->prev = NULL;
     newStudent->next = NULL;
    return newStudent;
// A. Display all students' information
void displayStudents() {
    struct Student* temp = head;
    printf("\nStudent List:\n");
    while (temp != NULL) {
   printf("Roll Number: %d, Name: %s\n", temp->rollNumber, temp-
>name);
        temp = temp->next;
// B. Display students' information in reverse order
void displayReverse() {
    struct Student* temp = head;
    if (temp == NULL) return;
    // Move to the last node
    while (temp->next != NULL) {
        temp = temp->next;
    printf("\nStudents in Reverse Order:\n");
    while (temp != NULL) {
   printf("Roll Number: %d, Name: %s\n", temp->rollNumber, temp-
>name);
        temp = temp->prev;
// C. Insert new student record at the start
void insertAtStart(int rollNumber, char name[]) {
    struct Student* newStudent = createStudent(rollNumber, name);
    if (head != NULL) {
        head->prev = newStudent;
    newStudent->next = head;
    head = newStudent;
// C. Insert new student record at the end
void insertAtEnd(int rollNumber, char name[]) {
    struct Student* newStudent = createStudent(rollNumber, name);
    if (head == NULL) {
        head = newStudent;
    } else {
        struct Student* temp = head;
        while (temp->next != NULL) {
            temp = temp->next;
        temp->next = newStudent;
        newStudent->prev = temp;
// C. Insert new student record in between (after a given roll number)
void insertInBetween(int rollNumber, char name[], int afterRoll) {
    struct Student* temp = head;
    while (temp != NULL && temp->rollNumber != afterRoll) {
        temp = temp->next;
    if (temp != NULL) {
        struct Student* newStudent = createStudent(rollNumber, name);
        newStudent->next = temp->next;
        newStudent->prev = temp;
        if (temp->next != NULL) {
            temp->next->prev = newStudent;
        temp->next = newStudent;
    } else {
        printf("Student with roll number %d not found.\n", afterRoll);
    }
}
// D. Delete an existing student record by roll number
void deleteStudent(int rollNumber) {
    struct Student* temp = head;
    while (temp != NULL && temp->rollNumber != rollNumber) {
        temp = temp->next;
    if (temp == NULL) {
        printf("Student with roll number %d not found.\n", rollNumber);
        return;
    if (temp->prev != NULL) {
        temp->prev->next = temp->next;
    } else {
        head = temp->next;
    if (temp->next != NULL) {
        temp->next->prev = temp->prev;
    free(temp);
    printf("Student with roll number %d deleted.\n", rollNumber);
}
// Main function
int main() {
  int choice, rollNumber, afterRoll;
  char name[50];
  while (1) {
    printf("\nMenu:\n");
    printf("1. Display all students\n");
    printf("2. Display students in reverse order\n");
    printf("3. Insert student at start\n");
    printf("4. Insert student at end\n");
    printf("5. Insert student in between\n");
    printf("6. Delete student\n");
    printf("7. Exit\n");
    printf("Enter your choice: ");
    scanf("%d", &choice);
    switch (choice) {
       case 1:
         displayStudents();
         break;
       case 2:
         displayReverse();
         break;
case 3:
  printf("Enter Roll Number and Name: ");
  scanf("%d", &rollNumber);
  getchar(); // to consume newline
  fgets(name, sizeof(name), stdin);
  name[strcspn(name, "\n")] = 0; // Remove newline character
  insertAtStart(rollNumber, name);
  break;
case 4:
  printf("Enter Roll Number and Name: ");
  scanf("%d", &rollNumber);
  getchar();
  fgets(name, sizeof(name), stdin);
  name[strcspn(name, "\n")] = 0;
  insertAtEnd(rollNumber, name);
  break;
case 5:
  printf("Enter Roll Number and Name to Insert: ");
  scanf("%d", &rollNumber);
  getchar();
  fgets(name, sizeof(name), stdin);
  name[strcspn(name, "\n")] = 0;
  printf("Enter Roll Number after which to insert: ");
  scanf("%d", &afterRoll);
              insertInBetween(rollNumber, name, afterRoll);
              break;
            case 6:
              printf("Enter Roll Number to Delete: ");
              scanf("%d", &rollNumber);
              deleteStudent(rollNumber);
              break;
            case 7:
              printf("Exiting...\n");
              exit(0);
            default:
              printf("Invalid choice! Please try again.\n");
    return 0;
}
Q 19 Write a program to perform following operations on student
database using circular single linked list. A. Display all students
information, B. Display information in reverse order, C. Insert new
students record in between, at last and at start, D. Delete existing
students record from its place.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
     int rollNo;
     char name[50];
     int age;
     struct Student* next;
};
struct Student* last = NULL;
// Function to create a new student node
struct Student* createStudent(int rollNo, char* name, int age) {
  struct Student* newStudent = (struct Student*)malloc(sizeof(struct
Student));
     newStudent->rollNo = rollNo;
     strcpy(newStudent->name, name);
     newStudent->age = age;
     newStudent->next = newStudent;
    return newStudent;
// A. Display all students' information
void displayStudents() {
    if (last == NULL) {
        printf("No records in the database.\n");
        return;
    struct Student* temp = last->next;
    do {
   printf("Roll No: %d, Name: %s, Age: %d\n", temp->rollNo, temp-
>name, temp->age);
        temp = temp->next;
    } while (temp != last->next);
// B. Display information in reverse order
void displayStudentsReverse(struct Student* start) {
    if (start->next != last->next) {
        displayStudentsReverse(start->next);
  printf("Roll No: %d, Name: %s, Age: %d\n", start->rollNo, start->name,
start->age);
}
// C1. Insert new student at the beginning
void insertAtStart(int rollNo, char* name, int age) {
    struct Student* newStudent = createStudent(rollNo, name, age);
    if (last == NULL) {
        last = newStudent;
    } else {
        newStudent->next = last->next;
        last->next = newStudent;
// C2. Insert new student at the end
void insertAtEnd(int rollNo, char* name, int age) {
    struct Student* newStudent = createStudent(rollNo, name, age);
    if (last == NULL) {
        last = newStudent;
    } else {
        newStudent->next = last->next;
        last->next = newStudent;
        last = newStudent;
}
// C3. Insert new student in between
void insertInBetween(int rollNo, char* name, int age, int pos) {
    struct Student* temp = last->next;
    int count = 1;
    while (count < pos - 1 && temp != last) {
        temp = temp->next;
        count++;
    if (count == pos - 1) {
        struct Student* newStudent = createStudent(rollNo, name, age);
        newStudent->next = temp->next;
        temp->next = newStudent;
        if (temp == last) {
            last = newStudent;
    } else {
        printf("Position out of range.\n");
// D. Delete existing student record
void deleteStudent(int rollNo) {
    if (last == NULL) {
        printf("No records in the database to delete.\n");
    return;
struct Student* temp = last->next, *prev;
if (temp->rollNo == rollNo) {
    if (temp == last) {
        free(temp);
        last = NULL;
    } else {
        last->next = temp->next;
        free(temp);
    printf("Record with Roll No %d deleted.\n", rollNo);
    return;
prev = temp;
temp = temp->next;
while (temp != last->next) {
    if (temp->rollNo == rollNo) {
        prev->next = temp->next;
        if (temp == last) last = prev;
        free(temp);
        printf("Record with Roll No %d deleted.\n", rollNo);
        return;
    }
        prev = temp;
        temp = temp->next;
    printf("Record with Roll No %d not found.\n", rollNo);
int main() {
    int choice, rollNo, age, pos;
    char name[50];
    while (1) {
        printf("\n1. Display All Students\n");
        printf("2. Display Students in Reverse\n");
        printf("3. Insert Student at Start\n");
        printf("4. Insert Student at End\n");
        printf("5. Insert Student in Between\n");
        printf("6. Delete Student\n");
        printf("7. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
          case 1:
             displayStudents();
  break;
case 2:
  if (last != NULL) {
      displayStudentsReverse(last->next);
  } else {
      printf("No records in the database.\n");
  break;
case 3:
  printf("Enter Roll No, Name, Age: ");
  scanf("%d %s %d", &rollNo, name, &age);
  insertAtStart(rollNo, name, age);
  break;
case 4:
  printf("Enter Roll No, Name, Age: ");
  scanf("%d %s %d", &rollNo, name, &age);
  insertAtEnd(rollNo, name, age);
  break;
case 5:
  printf("Enter Roll No, Name, Age, Position: ");
  scanf("%d %s %d %d", &rollNo, name, &age, &pos);
  insertInBetween(rollNo, name, age, pos);
  break;
case 6:
              printf("Enter Roll No to delete: ");
              scanf("%d", &rollNo);
              deleteStudent(rollNo);
              break;
            case 7:
              exit(0);
            default:
              printf("Invalid choice.\n");
    return 0;
}
Q 20 Write a program to perform following operations on student
database using circular double linked list. A. Display all students
information, B. Display information in reverse order, C. Insert new
students record in between, at last and at start, D. Delete existing
students record from its place.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
     int rollNo;
     char name[50];
     int age;
     struct Student* next;
     struct Student* prev;
};
struct Student* last = NULL;
// Function to create a new student node
struct Student* createStudent(int rollNo, char* name, int age) {
  struct Student* newStudent = (struct Student*)malloc(sizeof(struct
Student));
     newStudent->rollNo = rollNo;
     strcpy(newStudent->name, name);
     newStudent->age = age;
    newStudent->next = newStudent->prev = NULL;
    return newStudent;
// A. Display all students' information
void displayStudents() {
    if (last == NULL) {
        printf("No records in the database.\n");
        return;
    struct Student* temp = last->next;
    do {
   printf("Roll No: %d, Name: %s, Age: %d\n", temp->rollNo, temp-
>name, temp->age);
        temp = temp->next;
    } while (temp != last->next);
// B. Display information in reverse order
void displayStudentsReverse() {
    if (last == NULL) {
        printf("No records in the database.\n");
        return;
    struct Student* temp = last;
    do {
   printf("Roll No: %d, Name: %s, Age: %d\n", temp->rollNo, temp-
>name, temp->age);
        temp = temp->prev;
    } while (temp != last);
// C1. Insert new student at the beginning
void insertAtStart(int rollNo, char* name, int age) {
    struct Student* newStudent = createStudent(rollNo, name, age);
    if (last == NULL) {
        last = newStudent;
        last->next = last->prev = last;
    } else {
        newStudent->next = last->next;
        newStudent->prev = last;
        last->next->prev = newStudent;
        last->next = newStudent;
// C2. Insert new student at the end
void insertAtEnd(int rollNo, char* name, int age) {
    struct Student* newStudent = createStudent(rollNo, name, age);
    if (last == NULL) {
        last = newStudent;
        last->next = last->prev = last;
    } else {
        newStudent->next = last->next;
        newStudent->prev = last;
        last->next->prev = newStudent;
        last->next = newStudent;
        last = newStudent;
// C3. Insert new student in between
void insertInBetween(int rollNo, char* name, int age, int pos) {
    if (last == NULL) {
        printf("The list is empty.\n");
        return;
    struct Student* temp = last->next;
    int count = 1;
    while (count < pos - 1 && temp != last) {
        temp = temp->next;
        count++;
    if (count == pos - 1) {
        struct Student* newStudent = createStudent(rollNo, name, age);
        newStudent->next = temp->next;
        newStudent->prev = temp;
        temp->next->prev = newStudent;
        temp->next = newStudent;
        if (temp == last) {
            last = newStudent;
    } else {
        printf("Position out of range.\n");
// D. Delete existing student record
void deleteStudent(int rollNo) {
    if (last == NULL) {
        printf("No records in the database to delete.\n");
        return;
    struct Student* temp = last->next;
    if (temp->rollNo == rollNo) { // If the first node is to be deleted
        if (temp == last) { // Only one node in the list
            free(temp);
            last = NULL;
        } else {
            last->next = temp->next;
            temp->next->prev = last;
            free(temp);
        printf("Record with Roll No %d deleted.\n", rollNo);
        return;
    struct Student* prev = temp;
    temp = temp->next;
    while (temp != last->next) {
        if (temp->rollNo == rollNo) {
            prev->next = temp->next;
            temp->next->prev = prev;
            if (temp == last) last = prev;
            free(temp);
            printf("Record with Roll No %d deleted.\n", rollNo);
            return;
        prev = temp;
        temp = temp->next;
    printf("Record with Roll No %d not found.\n", rollNo);
}
int main() {
  int choice, rollNo, age, pos;
  char name[50];
  while (1) {
    printf("\n1. Display All Students\n");
    printf("2. Display Students in Reverse\n");
    printf("3. Insert Student at Start\n");
    printf("4. Insert Student at End\n");
    printf("5. Insert Student in Between\n");
    printf("6. Delete Student\n");
    printf("7. Exit\n");
    printf("Enter your choice: ");
    scanf("%d", &choice);
    switch (choice) {
       case 1:
         displayStudents();
         break;
       case 2:
         displayStudentsReverse();
         break;
       case 3:
      printf("Enter Roll No, Name, Age: ");
      scanf("%d %s %d", &rollNo, name, &age);
      insertAtStart(rollNo, name, age);
      break;
    case 4:
      printf("Enter Roll No, Name, Age: ");
      scanf("%d %s %d", &rollNo, name, &age);
      insertAtEnd(rollNo, name, age);
      break;
    case 5:
      printf("Enter Roll No, Name, Age, Position: ");
      scanf("%d %s %d %d", &rollNo, name, &age, &pos);
      insertInBetween(rollNo, name, age, pos);
      break;
    case 6:
      printf("Enter Roll No to delete: ");
      scanf("%d", &rollNo);
      deleteStudent(rollNo);
      break;
    case 7:
      exit(0);
    default:
      printf("Invalid choice.\n");
}
    }
    return 0;
}
Q21 Write a program to accept six digit integer number and store it in
circular double linked list (each digit in separate node) and perform
addition and subtraction operation on it. Also consider carry.
#include <stdio.h>
#include <stdlib.h>
struct Node {
     int digit;
     struct Node* next;
     struct Node* prev;
};
struct Node* head = NULL;
// Function to create a new node with a given digit
struct Node* createNode(int digit) {
     struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
     newNode->digit = digit;
     newNode->next = newNode;
     newNode->prev = newNode;
     return newNode;
// Function to insert digit at the end of the circular doubly linked list
void insertDigit(int digit) {
    struct Node* newNode = createNode(digit);
    if (head == NULL) {
        head = newNode;
    } else {
        struct Node* last = head->prev;
        last->next = newNode;
        newNode->prev = last;
        newNode->next = head;
        head->prev = newNode;
// Function to initialize the list with each digit of the input number
void createList(int number) {
    for (int i = 5; i >= 0; i--) {
        int digit = (number / (int)pow(10, i)) % 10;
        insertDigit(digit);
// Function to display the number from the circular doubly linked list
void displayNumber() {
    if (head == NULL) return;
    struct Node* temp = head;
    printf("Number: ");
    do {
        printf("%d", temp->digit);
        temp = temp->next;
    } while (temp != head);
    printf("\n");
// Function to add a number to the circular doubly linked list
void addNumber(int addend) {
    struct Node* temp = head->prev; // Start from the last node
    int carry = addend;
    while (temp != NULL && carry != 0) {
        int sum = temp->digit + carry;
        temp->digit = sum % 10;
        carry = sum / 10;
        temp = temp->prev;
    if (carry != 0) {
        printf("Overflow, addition not possible within six digits.\n");
    } else {
        displayNumber();
}
// Function to subtract a number from the circular doubly linked list
void subtractNumber(int subtrahend) {
    struct Node* temp = head->prev; // Start from the last node
    int borrow = subtrahend;
    while (temp != NULL && borrow != 0) {
        int diff = temp->digit - borrow;
        if (diff < 0) {
            temp->digit = 10 + diff;
            borrow = 1;
        } else {
            temp->digit = diff;
            borrow = 0;
        temp = temp->prev;
    if (borrow != 0) {
        printf("Underflow, subtraction not possible within six digits.\n");
    } else {
        displayNumber();
// Main function
int main() {
  int number, choice, operand;
  printf("Enter a six-digit integer number: ");
  scanf("%d", &number);
  if (number < 100000 || number > 999999) {
      printf("Please enter a valid six-digit number.\n");
      return 0;
  // Create list from input number
  createList(number);
  displayNumber();
  while (1) {
      printf("\nMenu:\n");
      printf("1. Add a number\n");
      printf("2. Subtract a number\n");
      printf("3. Exit\n");
      printf("Enter your choice: ");
      scanf("%d", &choice);
      switch (choice) {
        case 1:
              printf("Enter a number to add (0-999999): ");
              scanf("%d", &operand);
              addNumber(operand);
              break;
            case 2:
              printf("Enter a number to subtract (0-999999): ");
              scanf("%d", &operand);
              subtractNumber(operand);
              break;
            case 3:
              printf("Exiting...\n");
              exit(0);
            default:
              printf("Invalid choice! Please try again.\n");
    return 0;
}
Q 22 Write a program to accept six digit integer number and store it in
circular single linked list (each digit in separate node) and perform
addition and subtraction operation on it. Also consider carry.
#include <stdio.h>
#include <stdlib.h>
struct Node {
     int digit;
     struct Node* next;
};
// Function to create a new node with a digit
struct Node* createNode(int digit) {
     struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
     newNode->digit = digit;
     newNode->next = NULL;
     return newNode;
// Function to insert a node at the end of the circular linked list
void insertNode(struct Node** last, int digit) {
     struct Node* newNode = createNode(digit);
     if (*last == NULL) {
       *last = newNode;
        newNode->next = newNode; // Circular link
    } else {
        newNode->next = (*last)->next;
        (*last)->next = newNode;
        *last = newNode;
// Function to display the digits of the circular linked list
void displayList(struct Node* last) {
    if (last == NULL) {
        printf("The list is empty.\n");
        return;
    struct Node* temp = last->next;
    do {
        printf("%d", temp->digit);
        temp = temp->next;
    } while (temp != last->next);
    printf("\n");
// Function to add two circular linked lists
void addLists(struct Node* last1, struct Node* last2, struct Node**
resultLast) {
    struct Node* temp1 = last1->next;
    struct Node* temp2 = last2->next;
    int carry = 0;
    do {
        int sum = temp1->digit + temp2->digit + carry;
        carry = sum / 10;
        insertNode(resultLast, sum % 10);
        temp1 = temp1->next;
        temp2 = temp2->next;
    } while (temp1 != last1->next || temp2 != last2->next);
    // If carry is remaining, add a new node
    if (carry) {
        insertNode(resultLast, carry);
// Function to subtract two circular linked lists
void subtractLists(struct Node* last1, struct Node* last2, struct Node**
resultLast) {
    struct Node* temp1 = last1->next;
    struct Node* temp2 = last2->next;
    int borrow = 0;
    do {
        int diff = temp1->digit - temp2->digit - borrow;
        if (diff < 0) {
            diff += 10;
            borrow = 1;
        } else {
            borrow = 0;
        insertNode(resultLast, diff);
        temp1 = temp1->next;
        temp2 = temp2->next;
    } while (temp1 != last1->next || temp2 != last2->next);
// Function to accept a six-digit integer and store it in a circular linked
list
void acceptNumber(struct Node** last, int number) {
    int digit;
    while (number > 0) {
        digit = number % 10;
        insertNode(last, digit);
        number /= 10;
}
// Main function to perform operations
int main() {
  struct Node *last1 = NULL, *last2 = NULL, *resultLast = NULL;
  int num1, num2;
  // Accept two six-digit numbers
  printf("Enter first six-digit number: ");
  scanf("%d", &num1);
  printf("Enter second six-digit number: ");
  scanf("%d", &num2);
  // Store the numbers in circular linked lists
  acceptNumber(&last1, num1);
  acceptNumber(&last2, num2);
  printf("\nFirst number: ");
  displayList(last1);
  printf("Second number: ");
  displayList(last2);
  // Perform addition
  addLists(last1, last2, &resultLast);
  printf("\nSum: ");
  displayList(resultLast);
    // Reset result list for subtraction
    resultLast = NULL;
    subtractLists(last1, last2, &resultLast);
    printf("\nDifference: ");
    displayList(resultLast);
    return 0;
}
Q23 Write a program to accept two sorted double linked lists and
merge them in a single linked list in such a way that the resultant
linked list will be a sorted one.
#include <stdio.h>
#include <stdlib.h>
// Define the node structure for a doubly linked list
struct DNode {
     int data;
     struct DNode* prev;
     struct DNode* next;
};
// Define the node structure for a singly linked list
struct SNode {
     int data;
     struct SNode* next;
};
// Function to create a new doubly linked list node
struct DNode* createDNode(int data) {
     struct DNode* newNode = (struct DNode*)malloc(sizeof(struct DNode));
     newNode->data = data;
     newNode->prev = NULL;
     newNode->next = NULL;
     return newNode;
}
// Function to create a new singly linked list node
struct SNode* createSNode(int data) {
    struct SNode* newNode = (struct SNode*)malloc(sizeof(struct SNode));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}
// Function to append nodes to the doubly linked list
void appendDNode(struct DNode** head, int data) {
    struct DNode* newNode = createDNode(data);
    if (*head == NULL) {
        *head = newNode;
    } else {
        struct DNode* temp = *head;
        while (temp->next) {
            temp = temp->next;
        }
        temp->next = newNode;
        newNode->prev = temp;
    }
}
// Function to merge two sorted doubly linked lists into a sorted singly linked
list
struct SNode* mergeSortedDLists(struct DNode* head1, struct DNode* head2)
{
  struct SNode* resultHead = NULL;
  struct SNode* tail = NULL;
  while (head1 != NULL && head2 != NULL) {
      int value;
      if (head1->data < head2->data) {
          value = head1->data;
          head1 = head1->next;
      } else {
          value = head2->data;
          head2 = head2->next;
      }
      struct SNode* newNode = createSNode(value);
      if (resultHead == NULL) {
          resultHead = newNode;
          tail = newNode;
      } else {
          tail->next = newNode;
          tail = tail->next;
      }
  }
// Append remaining nodes from head1 or head2
while (head1 != NULL) {
    struct SNode* newNode = createSNode(head1->data);
    if (resultHead == NULL) {
        resultHead = newNode;
        tail = newNode;
    } else {
        tail->next = newNode;
        tail = tail->next;
    }
    head1 = head1->next;
}
while (head2 != NULL) {
    struct SNode* newNode = createSNode(head2->data);
    if (resultHead == NULL) {
        resultHead = newNode;
        tail = newNode;
    } else {
        tail->next = newNode;
        tail = tail->next;
    }
    head2 = head2->next;
}
return resultHead;
}
// Function to print the singly linked list
void printSList(struct SNode* head) {
    while (head) {
        printf("%d -> ", head->data);
        head = head->next;
    }
    printf("NULL\n");
}
int main() {
    struct DNode* head1 = NULL;
    struct DNode* head2 = NULL;
    int n1, n2, data;
    // Input number of nodes for the first doubly linked list
    printf("Enter the number of nodes for the first sorted doubly linked list: ");
    scanf("%d", &n1);
    printf("Enter the values for the first sorted doubly linked list: ");
    for (int i = 0; i < n1; i++) {
        scanf("%d", &data);
        appendDNode(&head1, data);
    }
    // Input number of nodes for the second doubly linked list
   printf("Enter the number of nodes for the second sorted doubly linked list:
");
    scanf("%d", &n2);
    printf("Enter the values for the second sorted doubly linked list: ");
    for (int i = 0; i < n2; i++) {
        scanf("%d", &data);
        appendDNode(&head2, data);
    }
    // Merge the two lists into a sorted singly linked list
    struct SNode* mergedList = mergeSortedDLists(head1, head2);
    // Print the merged singly linked list
    printf("Merged Sorted Singly Linked List: ");
    printSList(mergedList);
    return 0;
}
Q 24 Write a program to accept two sorted single linked lists
and merge them in a single linked list in such a way that the
resultant linked list will be a sorted one.
#include <stdio.h>
#include <stdlib.h>
// Define the structure for linked list node
struct Node {
     int data;
     struct Node* next;
};
// Function to create a new node
struct Node* newNode(int data) {
     struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
     temp->data = data;
     temp->next = NULL;
     return temp;
}
// Function to merge two sorted linked lists
struct Node* mergeSortedLists(struct Node* head1, struct Node* head2) {
     // If one of the lists is empty, return the other list
     if (head1 == NULL)
       return head2;
     if (head2 == NULL)
    return head1;
// Initialize the head of the merged list
struct Node* mergedHead = NULL;
// Start with the smaller element from the two lists
if (head1->data <= head2->data) {
    mergedHead = head1;
    head1 = head1->next;
} else {
    mergedHead = head2;
    head2 = head2->next;
}
// Pointer to keep track of the current node in the merged list
struct Node* mergedTail = mergedHead;
// Merge the two lists
while (head1 != NULL && head2 != NULL) {
    if (head1->data <= head2->data) {
        mergedTail->next = head1;
        head1 = head1->next;
    } else {
        mergedTail->next = head2;
        head2 = head2->next;
    }
        mergedTail = mergedTail->next;
    }
    // If there are remaining nodes in either list, append them
    if (head1 != NULL)
        mergedTail->next = head1;
    if (head2 != NULL)
        mergedTail->next = head2;
    return mergedHead;
}
// Function to print the linked list
void printList(struct Node* head) {
    struct Node* temp = head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}
// Function to input a linked list from the user
struct Node* inputList() {
    struct Node* head = NULL;
    struct Node* tail = NULL;
    int n, value;
    printf("Enter the number of elements in the list: ");
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        printf("Enter element %d: ", i + 1);
        scanf("%d", &value);
        struct Node* new_node = newNode(value);
        if (head == NULL) {
            head = new_node;
            tail = head;
        } else {
            tail->next = new_node;
            tail = tail->next;
        }
    }
    return head;
}
// Main function
int main() {
    // Input two sorted linked lists
    printf("Enter the first sorted linked list:\n");
    struct Node* list1 = inputList();
    printf("Enter the second sorted linked list:\n");
    struct Node* list2 = inputList();
    // Merging the two sorted linked lists
    struct Node* mergedList = mergeSortedLists(list1, list2);
    // Printing the merged sorted linked list
    printf("Merged Sorted Linked List: ");
    printList(mergedList);
    return 0;
}
Q 25 Write a program to implement following operations using stack. A.
Factorial of a given number B. Decimal to binary conversion
Implement a stack using Single linked list
#include <stdio.h>
#include <stdlib.h>
// Stack node structure using singly linked list
struct StackNode {
     int data;
     struct StackNode* next;
};
// Stack structure
struct Stack {
     struct StackNode* top;
};
// Function to create a new stack
struct Stack* createStack() {
     struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
     stack->top = NULL;
     return stack;
}
// Function to push an element onto the stack
void push(struct Stack* stack, int data) {
  struct StackNode* newNode = (struct StackNode*)malloc(sizeof(struct
StackNode));
    newNode->data = data;
    newNode->next = stack->top;
    stack->top = newNode;
}
// Function to pop an element from the stack
int pop(struct Stack* stack) {
    if (stack->top == NULL) {
        printf("Stack underflow!\n");
        return -1;
    }
    int data = stack->top->data;
    struct StackNode* temp = stack->top;
    stack->top = stack->top->next;
    free(temp);
    return data;
}
// Function to check if the stack is empty
int isEmpty(struct Stack* stack) {
    return stack->top == NULL;
}
// Function to calculate the factorial using stack
int factorial(int n) {
    struct Stack* stack = createStack();
    int result = 1;
    for (int i = n; i > 1; i--) {
        push(stack, i);
    }
    while (!isEmpty(stack)) {
        result *= pop(stack);
    }
    free(stack); // free stack after use
    return result;
}
// Function to convert a decimal number to binary using stack
void decimalToBinary(int n) {
    struct Stack* stack = createStack();
    // Edge case for 0
    if (n == 0) {
        printf("0");
        return;
    }
    // Push binary digits onto stack
    while (n > 0) {
        push(stack, n % 2);
        n = n / 2;
    }
    // Pop from stack to print the binary representation
    while (!isEmpty(stack)) {
        printf("%d", pop(stack));
    }
    free(stack); // free stack after use
}
int main() {
    int choice, number;
    printf("Stack Operations:\n");
    printf("1. Factorial of a given number\n");
    printf("2. Decimal to binary conversion\n");
    printf("Enter your choice: ");
    scanf("%d", &choice);
    switch (choice) {
        case 1:
          printf("Enter a number to find its factorial: ");
          scanf("%d", &number);
          printf("Factorial of %d is: %d\n", number, factorial(number));
          break;
        case 2:
          printf("Enter a decimal number to convert to binary: ");
          scanf("%d", &number);
          printf("Binary representation: ");
          decimalToBinary(number);
          printf("\n");
          break;
        default:
          printf("Invalid choice!\n");
          break;
    }
    return 0;
}
     Q 26Write a program to implement following operations using
stack. A. Factorial of a given number B. Decimal to binary conversion
         Implement a stack using Double linked list
#include <stdio.h>
#include <stdlib.h>
// Define the structure for doubly linked list node
struct Node {
     int data;
     struct Node* next;
     struct Node* prev;
};
// Define the structure for stack
struct Stack {
     struct Node* top;
};
// Function to create a new node
struct Node* newNode(int data) {
     struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
     temp->data = data;
     temp->next = NULL;
     temp->prev = NULL;
     return temp;
}
// Function to initialize the stack
void initStack(struct Stack* stack) {
    stack->top = NULL;
}
// Check if the stack is empty
int isEmpty(struct Stack* stack) {
    return (stack->top == NULL);
}
// Push an element onto the stack
void push(struct Stack* stack, int data) {
    struct Node* temp = newNode(data);
    if (isEmpty(stack)) {
        stack->top = temp;
    } else {
        temp->next = stack->top;
        stack->top->prev = temp;
        stack->top = temp;
    }
}
// Pop an element from the stack
int pop(struct Stack* stack) {
    if (isEmpty(stack)) {
        printf("Stack is empty!\n");
        return -1; // Return a sentinel value for empty stack
    }
    struct Node* temp = stack->top;
    int data = temp->data;
    stack->top = temp->next;
    if (stack->top != NULL) {
        stack->top->prev = NULL;
    }
    free(temp);
    return data;
}
// Function to calculate the factorial of a number using the stack
int factorial(struct Stack* stack, int n) {
    int fact = 1;
    for (int i = 1; i <= n; i++) {
        push(stack, i);
    }
    while (!isEmpty(stack)) {
        fact *= pop(stack);
    }
    return fact;
}
// Function to convert decimal to binary using the stack
void decimalToBinary(struct Stack* stack, int n) {
    if (n == 0) {
        printf("0");
        return;
    }
    while (n > 0) {
        push(stack, n % 2);
        n /= 2;
    }
    while (!isEmpty(stack)) {
        printf("%d", pop(stack));
    }
}
// Main function to test the operations
int main() {
    struct Stack stack;
    initStack(&stack);
    // Factorial calculation
    int num;
    printf("Enter a number to calculate factorial: ");
    scanf("%d", &num);
    int fact = factorial(&stack, num);
    printf("Factorial of %d is: %d\n", num, fact);
    // Decimal to Binary conversion
    printf("Enter a decimal number to convert to binary: ");
    scanf("%d", &num);
    printf("Binary representation of %d is: ", num);
    decimalToBinary(&stack, num);
    printf("\n");
    return 0;
}
Q27 Write a program to accept a string of parenthesis and check its validity
using stack. Implement stack using double linked list
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Doubly Linked List node structure for the stack
struct StackNode {
     char data;
     struct StackNode* prev;
     struct StackNode* next;
};
// Stack structure
struct Stack {
     struct StackNode* top;
};
// Function to create a new stack
struct Stack* createStack() {
     struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
     stack->top = NULL;
     return stack;
}
// Function to push an element onto the stack
void push(struct Stack* stack, char data) {
  struct StackNode* newNode = (struct StackNode*)malloc(sizeof(struct
StackNode));
    newNode->data = data;
    newNode->prev = NULL;
    newNode->next = stack->top;
    if (stack->top != NULL) {
        stack->top->prev = newNode;
    }
    stack->top = newNode;
}
// Function to pop an element from the stack
char pop(struct Stack* stack) {
    if (stack->top == NULL) {
        return -1; // Indicating stack is empty
    }
    char data = stack->top->data;
    struct StackNode* temp = stack->top;
    stack->top = stack->top->next;
    if (stack->top != NULL) {
        stack->top->prev = NULL;
    }
    free(temp);
    return data;
}
// Function to check if the stack is empty
int isEmpty(struct Stack* stack) {
    return stack->top == NULL;
}
// Function to check the validity of the parentheses string
int isValidParentheses(char* str) {
    struct Stack* stack = createStack();
    for (int i = 0; i < strlen(str); i++) {
      char ch = str[i];
      // If the character is an opening parenthesis, push it onto the stack
      if (ch == '(') {
          push(stack, ch);
      }
      // If it's a closing parenthesis, pop from the stack
      else if (ch == ')') {
      // If the stack is empty or the top of the stack isn't an opening
parenthesis, it's invalid
          if (isEmpty(stack) || pop(stack) != '(') {
              free(stack);
              return 0; // Not valid
          }
        }
    }
    // If the stack is empty, all parentheses were matched correctly
    int result = isEmpty(stack);
    free(stack); // Free memory after use
    return result;
}
int main() {
    char str[100];
    printf("Enter a string of parentheses: ");
    scanf("%s", str);
    if (isValidParentheses(str)) {
        printf("The parentheses string is valid.\n");
    } else {
        printf("The parentheses string is invalid.\n");
    }
    return 0;
}
Q28 Write a program to implement circular queue using circular single linked
list and perform Add, delete and display operations.
#include <stdio.h>
#include <stdlib.h>
// Define the structure for the node of the circular queue
struct Node {
     int data;
     struct Node* next;
};
// Define the structure for the circular queue
struct CircularQueue {
     struct Node* front;
     struct Node* rear;
};
// Function to create a new node
struct Node* newNode(int data) {
     struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
     temp->data = data;
     temp->next = NULL;
     return temp;
}
// Function to initialize the circular queue
void initQueue(struct CircularQueue* queue) {
    queue->front = queue->rear = NULL;
}
// Function to check if the queue is empty
int isEmpty(struct CircularQueue* queue) {
    return (queue->front == NULL);
}
// Function to enqueue (add) an element to the circular queue
void enqueue(struct CircularQueue* queue, int data) {
    struct Node* temp = newNode(data);
    if (isEmpty(queue)) {
        queue->front = queue->rear = temp;
        queue->rear->next = queue->front; // Point rear to front (circular)
    } else {
        queue->rear->next = temp;
        queue->rear = temp;
        queue->rear->next = queue->front; // Point rear to front (circular)
    }
    printf("%d enqueued to queue\n", data);
}
// Function to dequeue (delete) an element from the circular queue
int dequeue(struct CircularQueue* queue) {
    if (isEmpty(queue)) {
        printf("Queue is empty! Cannot dequeue.\n");
        return -1; // Return a sentinel value indicating queue is empty
    }
    int data = queue->front->data;
    if (queue->front == queue->rear) {
        free(queue->front);
        queue->front = queue->rear = NULL;
    } else {
        struct Node* temp = queue->front;
        queue->front = queue->front->next;
        queue->rear->next = queue->front; // Update rear to point to new front
        free(temp);
    }
    return data;
}
// Function to display the elements of the circular queue
void display(struct CircularQueue* queue) {
    if (isEmpty(queue)) {
        printf("Queue is empty! Nothing to display.\n");
        return;
    }
    struct Node* temp = queue->front;
    printf("Queue: ");
    do {
        printf("%d ", temp->data);
        temp = temp->next;
    } while (temp != queue->front); // Loop until we reach the front again
    printf("\n");
}
// Main function to test the circular queue implementation
int main() {
    struct CircularQueue queue;
    int choice, data;
    initQueue(&queue);
    while (1) {
      printf("\nMenu:\n");
      printf("1. Enqueue\n");
      printf("2. Dequeue\n");
      printf("3. Display Queue\n");
      printf("4. Exit\n");
      printf("Enter your choice: ");
      scanf("%d", &choice);
      switch (choice) {
        case 1:
           printf("Enter the element to enqueue: ");
           scanf("%d", &data);
           enqueue(&queue, data);
           break;
        case 2:
              data = dequeue(&queue);
              if (data != -1) {
                  printf("Dequeued element: %d\n", data);
              }
              break;
            case 3:
              display(&queue);
              break;
            case 4:
              printf("Exiting the program.\n");
              return 0;
            default:
              printf("Invalid choice, please try again.\n");
        }
    }
}
       Q29 Write a program to implement Josephus problem using
circular double linked list.
#include <stdio.h>
#include <stdlib.h>
// Define the structure for the node of the doubly linked list
struct Node {
     int data;
     struct Node* next;
     struct Node* prev;
};
// Function to create a new node
struct Node* newNode(int data) {
     struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
     temp->data = data;
     temp->next = temp->prev = NULL;
     return temp;
}
// Function to create a doubly linked list with n nodes
struct Node* createDoublyLinkedList(int n) {
     struct Node* head = newNode(1); // Create the first node
     struct Node* temp = head;
     // Create remaining nodes and link them in a doubly linked manner
     for (int i = 2; i <= n; i++) {
        struct Node* new_node = newNode(i);
        temp->next = new_node;
        new_node->prev = temp;
        temp = temp->next;
    }
    temp->next = head; // Make the list circular by linking last node to head
  head->prev = temp; // Make the list circular by linking head's prev to last
node
    return head;
}
// Function to find the Josephus position
int josephus(int n, int k) {
    struct Node* head = createDoublyLinkedList(n);
    struct Node* temp = head;
    while (n > 1) {
        // Traverse to the k-th node
        for (int i = 1; i < k; i++) {
            temp = temp->next;
        }
        // Eliminate the k-th person
        struct Node* toDelete = temp->next;
        // Update pointers to remove the node
        temp->next = toDelete->next;
        toDelete->next->prev = temp;
        free(toDelete);
        n--;
    }
    // Return the position of the last remaining person
    int lastPerson = temp->data;
    free(temp); // Free the last remaining node
    return lastPerson;
}
// Main function to test the Josephus problem
int main() {
    int n, k;
    printf("Enter the number of people (n): ");
    scanf("%d", &n);
    printf("Enter the step size (k): ");
    scanf("%d", &k);
    // Solve the Josephus problem
    int lastPerson = josephus(n, k);
    printf("The last remaining person is at position: %d\n", lastPerson);
    return 0;
}
Q30 Write a program to implement Josephus problem using
circular single linked list.
#include <stdio.h>
#include <stdlib.h>
// Define the structure for the node of the circular linked list
struct Node {
     int data;
     struct Node* next;
};
// Function to create a new node
struct Node* newNode(int data) {
     struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
     temp->data = data;
     temp->next = NULL;
     return temp;
}
// Function to create a circular linked list with n nodes
struct Node* createCircularList(int n) {
     struct Node* head = newNode(1); // Create the first node
     struct Node* temp = head;
     // Create remaining nodes and link them in a circular manner
     for (int i = 2; i <= n; i++) {
       struct Node* new_node = newNode(i);
        temp->next = new_node;
        temp = temp->next;
    }
    temp->next = head; // Make the list circular by linking last node to head
    return head;
}
// Function to find the Josephus position
int josephus(int n, int k) {
    struct Node* head = createCircularList(n);
    struct Node* temp = head;
    while (n > 1) {
        // Traverse to the k-th node
        for (int i = 1; i < k; i++) {
            temp = temp->next;
        }
        // Eliminate the k-th person
        struct Node* toDelete = temp->next;
        temp->next = toDelete->next;
        free(toDelete);
        n--;
    }
    // Return the position of the last remaining person
    int lastPerson = temp->data;
    free(temp); // Free the last remaining node
    return lastPerson;
}
// Main function to test the Josephus problem
int main() {
    int n, k;
    printf("Enter the number of people (n): ");
    scanf("%d", &n);
    printf("Enter the step size (k): ");
    scanf("%d", &k);
    // Solve the Josephus problem
    int lastPerson = josephus(n, k);
    printf("The last remaining person is at position: %d\n", lastPerson);
    return 0;
}
Q31 Write a program to implement double ended queue using double linked
list and perform Add, delete and display operations.
#include <stdio.h>
#include <stdlib.h>
// Define the structure for the node of the doubly linked list
struct Node {
     int data;
     struct Node* next;
     struct Node* prev;
};
// Define the structure for the deque (double-ended queue)
struct Deque {
     struct Node* front;
     struct Node* rear;
};
// Function to create a new node
struct Node* newNode(int data) {
     struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
     temp->data = data;
     temp->next = temp->prev = NULL;
     return temp;
}
// Function to initialize the deque
void initDeque(struct Deque* deque) {
    deque->front = deque->rear = NULL;
}
// Function to check if the deque is empty
int isEmpty(struct Deque* deque) {
    return (deque->front == NULL);
}
// Add element to the front of the deque
void addFront(struct Deque* deque, int data) {
    struct Node* temp = newNode(data);
    if (isEmpty(deque)) {
        deque->front = deque->rear = temp;
    } else {
        temp->next = deque->front;
        deque->front->prev = temp;
        deque->front = temp;
    }
    printf("%d added to the front\n", data);
}
// Add element to the rear of the deque
void addRear(struct Deque* deque, int data) {
    struct Node* temp = newNode(data);
    if (isEmpty(deque)) {
        deque->front = deque->rear = temp;
    } else {
        temp->prev = deque->rear;
        deque->rear->next = temp;
        deque->rear = temp;
    }
    printf("%d added to the rear\n", data);
}
// Delete element from the front of the deque
int deleteFront(struct Deque* deque) {
    if (isEmpty(deque)) {
        printf("Deque is empty! Cannot delete from front.\n");
        return -1; // Return a sentinel value indicating deque is empty
    }
    int data = deque->front->data;
    struct Node* temp = deque->front;
    if (deque->front == deque->rear) { // Only one element in the deque
        deque->front = deque->rear = NULL;
    } else {
        deque->front = deque->front->next;
        deque->front->prev = NULL;
    }
    free(temp);
    return data;
}
// Delete element from the rear of the deque
int deleteRear(struct Deque* deque) {
    if (isEmpty(deque)) {
        printf("Deque is empty! Cannot delete from rear.\n");
        return -1; // Return a sentinel value indicating deque is empty
    }
    int data = deque->rear->data;
    struct Node* temp = deque->rear;
    if (deque->front == deque->rear) { // Only one element in the deque
        deque->front = deque->rear = NULL;
    } else {
        deque->rear = deque->rear->prev;
        deque->rear->next = NULL;
    }
    free(temp);
    return data;
}
// Function to display the elements of the deque
void display(struct Deque* deque) {
    if (isEmpty(deque)) {
        printf("Deque is empty! Nothing to display.\n");
        return;
    }
    struct Node* temp = deque->front;
    printf("Deque: ");
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}
// Main function to test the deque operations
int main() {
    struct Deque deque;
    int choice, data;
    initDeque(&deque);
    while (1) {
        // Menu-driven approach
        printf("\nMenu:\n");
        printf("1. Add to Front\n");
        printf("2. Add to Rear\n");
        printf("3. Delete from Front\n");
        printf("4. Delete from Rear\n");
        printf("5. Display Deque\n");
        printf("6. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
switch (choice) {
  case 1:
    printf("Enter the element to add to front: ");
    scanf("%d", &data);
    addFront(&deque, data);
    break;
  case 2:
    printf("Enter the element to add to rear: ");
    scanf("%d", &data);
    addRear(&deque, data);
    break;
  case 3:
    data = deleteFront(&deque);
    if (data != -1) {
        printf("Deleted from front: %d\n", data);
    }
    break;
  case 4:
    data = deleteRear(&deque);
    if (data != -1) {
        printf("Deleted from rear: %d\n", data);
    }
    break;
  case 5:
    display(&deque);
              break;
            case 6:
              printf("Exiting program.\n");
              return 0;
            default:
              printf("Invalid choice, please try again.\n");
        }
    }
    return 0;
}
Q 32Write a program to accept a string from user and store its each character
in a separate node of circular single linked list and check whether the entered
string is a palindrome or not.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Node structure for circular singly linked list
struct Node {
     char data;
     struct Node* next;
};
// Function to create a new node
struct Node* createNode(char data) {
     struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
     newNode->data = data;
     newNode->next = NULL;
     return newNode;
}
// Function to insert a new node at the end of the circular linked list
void insertNode(struct Node** head, char data) {
     struct Node* newNode = createNode(data);
     if (*head == NULL) {
       *head = newNode;
       newNode->next = *head; // Circular link
    } else {
        struct Node* temp = *head;
        // Traverse to the last node
        while (temp->next != *head) {
            temp = temp->next;
        }
        temp->next = newNode;
        newNode->next = *head; // Circular link
    }
}
// Function to find the middle of the circular list
struct Node* findMiddle(struct Node* head) {
    struct Node *slow = head, *fast = head;
    // Move fast two steps and slow one step at a time
    while (fast->next != head && fast->next->next != head) {
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow; // Middle node
}
// Function to reverse a circular linked list starting from a given node
struct Node* reverseList(struct Node* head) {
    struct Node *prev = NULL, *current = head, *next = NULL;
    do {
        next = current->next;
        current->next = prev;
        prev = current;
        current = next;
    } while (current != head);
    head->next = prev; // Connect the last node back to the reversed part
    return prev; // Return the new head of the reversed list
}
// Function to check if the string is a palindrome using the circular linked list
int isPalindrome(struct Node* head) {
    if (head == NULL || head->next == head) {
        return 1; // Empty or single character list is a palindrome
    }
    // Step 1: Find the middle of the list
    struct Node* middle = findMiddle(head);
    // Step 2: Reverse the second half starting from the node after the middle
    struct Node* secondHalf = middle->next;
    middle->next = head; // Close the first half to the head to form a circular list
    secondHalf = reverseList(secondHalf); // Reverse the second half
    // Step 3: Compare the first half with the reversed second half
    struct Node* firstHalf = head;
    while (secondHalf != head) {
        if (firstHalf->data != secondHalf->data) {
            return 0; // Not a palindrome
        }
        firstHalf = firstHalf->next;
        secondHalf = secondHalf->next;
    }
    return 1; // Palindrome
}
int main() {
    char str[100];
    struct Node* head = NULL;
    printf("Enter a string: ");
    scanf("%s", str);
    // Insert each character of the string into the circular linked list
    for (int i = 0; i < strlen(str); i++) {
        insertNode(&head, str[i]);
    }
    // Check if the string is a palindrome
    if (isPalindrome(head)) {
        printf("The entered string is a palindrome.\n");
    } else {
        printf("The entered string is not a palindrome.\n");
    }
    return 0;
}
Q33 -Implenet Queue using array.
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct {
    int items[MAX];
    int front;
    int rear;
} Queue;
// Function to initialize the queue
void initializeQueue(Queue *q) {
    q->front = -1;
    q->rear = -1;
}
// Function to check if the queue is full
int isFull(Queue *q) {
    return q->rear == MAX - 1;
}
// Function to check if the queue is empty
int isEmpty(Queue *q) {
    return q->front == -1 || q->front > q->rear;
}
// Function to add an element to the queue
void enqueue(Queue *q, int value) {
    if (isFull(q)) {
        printf("Queue is full!\n");
    } else {
        if (isEmpty(q)) {
            q->front = 0;
        }
        q->rear++;
        q->items[q->rear] = value;
        printf("Enqueued %d\n", value);
    }
}
// Function to remove an element from the queue
int dequeue(Queue *q) {
    int item;
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return -1;
    } else {
        item = q->items[q->front];
        q->front++;
        if (q->front > q->rear) {
            q->front = q->rear = -1;
        }
        printf("Dequeued %d\n", item);
        return item;
    }
}
// Function to print the queue
void printQueue(Queue *q) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
    } else {
        printf("The Queue Is: ");
        for (int i = q->front; i <= q->rear; i++) {
            printf("%d ", q->items[i]);
        }
        printf("\n");
    }
}
// Main function with menu-driven interface
int main() {
    Queue q;
    initializeQueue(&q);
    int choice, value;
    while (1) {
        printf("\nQueue Menu:\n");
        printf("1. Enqueue\n");
        printf("2. Dequeue\n");
        printf("3. Print Queue\n");
        printf("4. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
            case 1:
              printf("Enter the value to enqueue: ");
              scanf("%d", &value);
              enqueue(&q, value);
              break;
            case 2:
              dequeue(&q);
              break;
            case 3:
              printQueue(&q);
              break;
            case 4:
              printf("Exiting...\n");
              exit(0);
            default:
              printf("Invalid choice! Please try again.\n");
        }
    }
    return 0;
}
Q34 Write a program to implement a circular queue and perform
the following operations on it. Addq, Delq, Display entire queue.
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 5 // Size of the circular queue
// Define a structure for the circular queue
struct CircularQueue {
     int items[MAX];
     int front;
     int rear;
};
// Initialize the queue
void initQueue(struct CircularQueue* q) {
     q->front = -1;
     q->rear = -1;
}
// Function to check if the queue is full
int isFull(struct CircularQueue* q) {
  return (q->front == 0 && q->rear == MAX - 1) || (q->rear == (q->front - 1) %
(MAX - 1));
}
// Function to check if the queue is empty
int isEmpty(struct CircularQueue* q) {
    return q->front == -1;
}
// Function to add an element to the circular queue
void Addq(struct CircularQueue* q, int value) {
    if (isFull(q)) {
        printf("Queue is Full\n");
        return;
    } else if (isEmpty(q)) { // First element to insert
        q->front = q->rear = 0;
    } else if (q->rear == MAX - 1 && q->front != 0) {
        q->rear = 0;
    } else {
        q->rear++;
    }
    q->items[q->rear] = value;
    printf("Inserted %d\n", value);
}
// Function to delete an element from the circular queue
void Delq(struct CircularQueue* q) {
    if (isEmpty(q)) {
        printf("Queue is Empty\n");
        return;
    }
    int removedValue = q->items[q->front];
    q->items[q->front] = -1; // Mark as removed
    if (q->front == q->rear) { // Queue has only one element
        q->front = q->rear = -1;
    } else if (q->front == MAX - 1) {
        q->front = 0;
    } else {
        q->front++;
    }
    printf("Deleted %d\n", removedValue);
}
// Function to display the entire circular queue
void Display(struct CircularQueue* q) {
    if (isEmpty(q)) {
        printf("Queue is Empty\n");
        return;
    }
    printf("Queue elements are: ");
    if (q->rear >= q->front) {
        for (int i = q->front; i <= q->rear; i++)
          printf("%d ", q->items[i]);
    } else {
        for (int i = q->front; i < MAX; i++)
          printf("%d ", q->items[i]);
        for (int i = 0; i <= q->rear; i++)
          printf("%d ", q->items[i]);
    }
    printf("\n");
}
int main() {
    struct CircularQueue q;
    initQueue(&q);
    int choice, value;
    while (1) {
        printf("\nCircular Queue Menu:\n");
        printf("1. Add element to queue (Addq)\n");
        printf("2. Delete element from queue (Delq)\n");
        printf("3. Display entire queue\n");
        printf("4. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
          case 1:
               printf("Enter the value to add: ");
              scanf("%d", &value);
              Addq(&q, value);
              break;
            case 2:
              Delq(&q);
              break;
            case 3:
              Display(&q);
              break;
            case 4:
              exit(0);
            default:
              printf("Invalid choice, please try again.\n");
        }
    }
    return 0;
}
Q 35-Write a program to implement a double-ended queue where
the user can remove the element from both the front and rear ends
of the queue.
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct {
    int items[MAX];
    int front;
    int rear;
} Deque;
// Function to initialize the deque
void initializeDeque(Deque *dq) {
    dq->front = -1;
    dq->rear = -1;
}
// Function to check if the deque is full
int isFull(Deque *dq) {
  return (dq->front == 0 && dq->rear == MAX - 1) || (dq->front ==
dq->rear + 1);
}
// Function to check if the deque is empty
int isEmpty(Deque *dq) {
    return dq->front == -1;
}
// Function to add an element to the front of the deque
void enqueueFront(Deque *dq, int value) {
    if (isFull(dq)) {
        printf("Deque is full!\n");
    } else {
        if (isEmpty(dq)) { // If empty, initialize front and rear to 0
            dq->front = dq->rear = 0;
        } else if (dq->front == 0) { // Wrap around
            dq->front = MAX - 1;
        } else {
            dq->front--;
        }
        dq->items[dq->front] = value;
        printf("Enqueued %d at the front\n", value);
    }
}
// Function to add an element to the rear of the deque
void enqueueRear(Deque *dq, int value) {
    if (isFull(dq)) {
        printf("Deque is full!\n");
    } else {
        if (isEmpty(dq)) { // If empty, initialize front and rear to 0
            dq->front = dq->rear = 0;
        } else if (dq->rear == MAX - 1) { // Wrap around
            dq->rear = 0;
        } else {
            dq->rear++;
        }
        dq->items[dq->rear] = value;
        printf("Enqueued %d at the rear\n", value);
    }
}
// Function to remove an element from the front of the deque
int dequeueFront(Deque *dq) {
    if (isEmpty(dq)) {
        printf("Deque is empty!\n");
        return -1;
    } else {
        int item = dq->items[dq->front];
        if (dq->front == dq->rear) { // Queue becomes empty
            dq->front = dq->rear = -1;
        } else if (dq->front == MAX - 1) { // Wrap around
            dq->front = 0;
        } else {
            dq->front++;
        }
        printf("Dequeued %d from the front\n", item);
        return item;
    }
}
// Function to remove an element from the rear of the deque
int dequeueRear(Deque *dq) {
    if (isEmpty(dq)) {
        printf("Deque is empty!\n");
        return -1;
    } else {
        int item = dq->items[dq->rear];
        if (dq->front == dq->rear) { // Queue becomes empty
            dq->front = dq->rear = -1;
        } else if (dq->rear == 0) { // Wrap around
            dq->rear = MAX - 1;
        } else {
            dq->rear--;
        }
        printf("Dequeued %d from the rear\n", item);
        return item;
    }
}
// Function to print the deque
void printDeque(Deque *dq) {
    if (isEmpty(dq)) {
        printf("Deque is empty!\n");
    } else {
        printf("The Deque is: ");
        int i = dq->front;
        while (1) {
            printf("%d ", dq->items[i]);
            if (i == dq->rear) break;
            i = (i + 1) % MAX;
        }
        printf("\n");
    }
}
// Main function with menu-driven interface
int main() {
Deque dq;
initializeDeque(&dq);
int choice, value;
while (1) {
  printf("\nDeque Menu:\n");
  printf("1. Enqueue at Front\n");
  printf("2. Enqueue at Rear\n");
  printf("3. Dequeue from Front\n");
  printf("4. Dequeue from Rear\n");
  printf("5. Print Deque\n");
  printf("6. Exit\n");
  printf("Enter your choice: ");
  scanf("%d", &choice);
  switch (choice) {
    case 1:
       printf("Enter the value to enqueue at the front: ");
       scanf("%d", &value);
       enqueueFront(&dq, value);
       break;
    case 2:
      printf("Enter the value to enqueue at the rear: ");
      scanf("%d", &value);
      enqueueRear(&dq, value);
      break;
    case 3:
      dequeueFront(&dq);
      break;
    case 4:
      dequeueRear(&dq);
      break;
    case 5:
      printDeque(&dq);
      break;
    case 6:
      printf("Exiting...\n");
      exit(0);
    default:
      printf("Invalid choice! Please try again.\n");
}
    }
    return 0;
}
Q36 -Write a program to implement a circular double-ended queue
where the user can add and remove the elements from both the
front and rear ends of the queue.
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 5 // Size of the circular deque
// Define a structure for the circular deque
struct CircularDeque {
     int items[MAX];
     int front;
     int rear;
};
// Initialize the deque
void initDeque(struct CircularDeque* dq) {
     dq->front = -1;
     dq->rear = -1;
}
// Function to check if the deque is full
int isFull(struct CircularDeque* dq) {
  return (dq->front == 0 && dq->rear == MAX - 1) || (dq->rear ==
(dq->front - 1) % (MAX - 1));
}
// Function to check if the deque is empty
int isEmpty(struct CircularDeque* dq) {
    return dq->front == -1;
}
// Function to add an element at the front of the deque
void addFront(struct CircularDeque* dq, int value) {
    if (isFull(dq)) {
        printf("Deque is Full\n");
        return;
    }
    if (isEmpty(dq)) { // First element to insert
        dq->front = dq->rear = 0;
    } else if (dq->front == 0) {
        dq->front = MAX - 1;
    } else {
        dq->front--;
    }
    dq->items[dq->front] = value;
    printf("Inserted %d at front\n", value);
}
// Function to add an element at the rear of the deque
void addRear(struct CircularDeque* dq, int value) {
    if (isFull(dq)) {
        printf("Deque is Full\n");
        return;
    }
    if (isEmpty(dq)) { // First element to insert
        dq->front = dq->rear = 0;
    } else if (dq->rear == MAX - 1) {
        dq->rear = 0;
    } else {
        dq->rear++;
    }
    dq->items[dq->rear] = value;
    printf("Inserted %d at rear\n", value);
}
// Function to delete an element from the front of the deque
void delFront(struct CircularDeque* dq) {
    if (isEmpty(dq)) {
        printf("Deque is Empty\n");
        return;
    }
    int removedValue = dq->items[dq->front];
    dq->items[dq->front] = -1; // Mark as removed
    if (dq->front == dq->rear) { // Deque has only one element
        dq->front = dq->rear = -1;
    } else if (dq->front == MAX - 1) {
        dq->front = 0;
    } else {
        dq->front++;
    }
    printf("Deleted %d from front\n", removedValue);
}
// Function to delete an element from the rear of the deque
void delRear(struct CircularDeque* dq) {
    if (isEmpty(dq)) {
        printf("Deque is Empty\n");
        return;
    }
    int removedValue = dq->items[dq->rear];
    dq->items[dq->rear] = -1; // Mark as removed
    if (dq->front == dq->rear) { // Deque has only one element
        dq->front = dq->rear = -1;
    } else if (dq->rear == 0) {
        dq->rear = MAX - 1;
    } else {
        dq->rear--;
    }
    printf("Deleted %d from rear\n", removedValue);
}
// Function to display the entire deque
void display(struct CircularDeque* dq) {
    if (isEmpty(dq)) {
        printf("Deque is Empty\n");
        return;
    }
    printf("Deque elements are: ");
    if (dq->rear >= dq->front) {
        for (int i = dq->front; i <= dq->rear; i++)
          printf("%d ", dq->items[i]);
    } else {
        for (int i = dq->front; i < MAX; i++)
          printf("%d ", dq->items[i]);
        for (int i = 0; i <= dq->rear; i++)
          printf("%d ", dq->items[i]);
    }
    printf("\n");
}
int main() {
    struct CircularDeque dq;
    initDeque(&dq);
    int choice, value;
    while (1) {
        printf("\nCircular Deque Menu:\n");
        printf("1. Add element to front\n");
        printf("2. Add element to rear\n");
        printf("3. Delete element from front\n");
        printf("4. Delete element from rear\n");
        printf("5. Display deque\n");
        printf("6. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
          case 1:
            printf("Enter the value to add at front: ");
            scanf("%d", &value);
              addFront(&dq, value);
              break;
            case 2:
              printf("Enter the value to add at rear: ");
              scanf("%d", &value);
              addRear(&dq, value);
              break;
            case 3:
              delFront(&dq);
              break;
            case 4:
              delRear(&dq);
              break;
            case 5:
              display(&dq);
              break;
            case 6:
              exit(0);
            default:
              printf("Invalid choice, please try again.\n");
        }
    }
    return 0;
}
Q37-write a program for a Bank simulation of its teller
operations to see how waiting times would be affected by
adding another teller.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_CUSTOMERS 100
#define MAX_SERVICE_TIME 10
#define MAX_ARRIVAL_TIME 5
typedef struct {
  int arrivalTime;
  int serviceTime;
  int waitingTime;
} Customer;
typedef struct {
  Customer customers[MAX_CUSTOMERS];
  int front;
  int rear;
} Queue;
void initializeQueue(Queue *q) {
    q->front = -1;
    q->rear = -1;
}
int isEmpty(Queue *q) {
    return q->front == -1 || q->front > q->rear;
}
int isFull(Queue *q) {
    return q->rear == MAX_CUSTOMERS - 1;
}
void enqueue(Queue *q, Customer customer) {
    if (!isFull(q)) {
        if (isEmpty(q)) {
            q->front = 0;
        }
        q->rear++;
        q->customers[q->rear] = customer;
    }
}
Customer dequeue(Queue *q) {
    Customer customer = {0, 0, 0};
    if (!isEmpty(q)) {
        customer = q->customers[q->front];
        q->front++;
        if (q->front > q->rear) {
            q->front = q->rear = -1;
        }
    }
    return customer;
}
// Function to simulate single teller system
float simulateSingleTeller(Queue *queue, int totalCustomers) {
    int currentTime = 0;
    int totalWaitingTime = 0;
    for (int i = 0; i < totalCustomers; i++) {
        Customer customer = dequeue(queue);
        if (currentTime < customer.arrivalTime) {
            currentTime = customer.arrivalTime;
        }
        customer.waitingTime = currentTime - customer.arrivalTime;
        totalWaitingTime += customer.waitingTime;
        currentTime += customer.serviceTime;
    }
    return (float)totalWaitingTime / totalCustomers;
}
// Function to simulate two tellers system
float simulateTwoTellers(Queue *queue, int totalCustomers) {
    int currentTime1 = 0, currentTime2 = 0;
    int totalWaitingTime = 0;
    for (int i = 0; i < totalCustomers; i++) {
        Customer customer = dequeue(queue);
   int *currentTime = (currentTime1 <= currentTime2) ?
¤tTime1 : ¤tTime2;
        if (*currentTime < customer.arrivalTime) {
            *currentTime = customer.arrivalTime;
        }
        customer.waitingTime = *currentTime - customer.arrivalTime;
        totalWaitingTime += customer.waitingTime;
        *currentTime += customer.serviceTime;
    }
    return (float)totalWaitingTime / totalCustomers;
}
int main() {
    Queue queue;
    initializeQueue(&queue);
    srand(time(NULL));
    int totalCustomers;
    printf("Enter the number of customers: ");
    scanf("%d", &totalCustomers);
    // Generate random customers with arrival and service times
    for (int i = 0; i < totalCustomers; i++) {
        Customer customer;
    customer.arrivalTime = (i == 0) ? 0 :
queue.customers[queue.rear].arrivalTime + (rand() %
MAX_ARRIVAL_TIME + 1);
        customer.serviceTime = rand() % MAX_SERVICE_TIME + 1;
        enqueue(&queue, customer);
    }
    // Display generated customer data
    printf("\nCustomer Data:\n");
    printf("Customer\tArrival Time\tService Time\n");
  for (int i = queue.front; i <= queue.rear; i++) {
   printf("%d\t\t%d\t\t%d\n", i + 1,
queue.customers[i].arrivalTime, queue.customers[i].serviceTime);
  }
  // Run simulations
  float avgWaitTimeSingle = simulateSingleTeller(&queue,
totalCustomers);
  initializeQueue(&queue); // Re-initialize for the next simulation
  // Generate customers again for consistent results across
simulations
  for (int i = 0; i < totalCustomers; i++) {
      Customer customer;
    customer.arrivalTime = (i == 0) ? 0 :
queue.customers[queue.rear].arrivalTime + (rand() %
MAX_ARRIVAL_TIME + 1);
      customer.serviceTime = rand() % MAX_SERVICE_TIME + 1;
      enqueue(&queue, customer);
  }
  float avgWaitTimeTwo = simulateTwoTellers(&queue,
totalCustomers);
  // Display results
    printf("\nAverage Waiting Time:\n");
    printf("Single Teller: %.2f minutes\n", avgWaitTimeSingle);
    printf("Two Tellers: %.2f minutes\n", avgWaitTimeTwo);
    return 0;
}
Q38- write a program to keep track of patients as they enter a
medical clinic, assigning patients to the doctor on a first-come, first-
serve basis.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5 // Maximum number of patients in the queue
// Define a structure for a patient
struct Patient {
     int id;
     char name[30];
};
// Define a structure for the queue
struct Queue {
     struct Patient patients[MAX];
     int front;
     int rear;
};
// Initialize the queue
void initQueue(struct Queue* q) {
    q->front = -1;
    q->rear = -1;
}
// Check if the queue is full
int isFull(struct Queue* q) {
    return (q->rear + 1) % MAX == q->front;
}
// Check if the queue is empty
int isEmpty(struct Queue* q) {
    return q->front == -1;
}
// Add a patient to the queue
void addPatient(struct Queue* q, int id, char* name) {
    if (isFull(q)) {
        printf("Queue is full. Please wait.\n");
        return;
    }
    if (isEmpty(q)) {
        q->front = q->rear = 0;
    } else {
        q->rear = (q->rear + 1) % MAX;
    }
    q->patients[q->rear].id = id;
    strcpy(q->patients[q->rear].name, name);
    printf("Patient %s (ID: %d) added to the queue.\n", name, id);
}
// Remove a patient from the queue (first-come, first-serve)
void servePatient(struct Queue* q) {
    if (isEmpty(q)) {
        printf("No patients in the queue.\n");
        return;
    }
  printf("Serving patient %s (ID: %d)\n", q->patients[q->front].name,
q->patients[q->front].id);
    if (q->front == q->rear) { // Only one patient in the queue
        q->front = q->rear = -1;
    } else {
        q->front = (q->front + 1) % MAX;
    }
}
// Display all patients in the queue
void displayQueue(struct Queue* q) {
    if (isEmpty(q)) {
        printf("No patients in the queue.\n");
        return;
    }
    printf("Patients in the queue:\n");
    int i = q->front;
    while (1) {
    printf("ID: %d, Name: %s\n", q->patients[i].id, q-
>patients[i].name);
        if (i == q->rear) break;
        i = (i + 1) % MAX;
    }
}
int main() {
    struct Queue queue;
    initQueue(&queue);
    int choice, id;
    char name[30];
while (1) {
  printf("\nClinic Queue Management System:\n");
  printf("1. Add a patient\n");
  printf("2. Serve a patient\n");
  printf("3. Display all patients in queue\n");
  printf("4. Exit\n");
  printf("Enter your choice: ");
  scanf("%d", &choice);
  switch (choice) {
    case 1:
       printf("Enter patient ID: ");
       scanf("%d", &id);
       printf("Enter patient name: ");
       scanf("%s", name);
       addPatient(&queue, id, name);
       break;
    case 2:
       servePatient(&queue);
       break;
    case 3:
       displayQueue(&queue);
       break;
            case 4:
              exit(0);
            default:
              printf("Invalid choice. Please try again.\n");
        }
    }
    return 0;
}
Q39 write a program to implement josephus problem.
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
// Queue structure
typedef struct {
    int items[MAX];
    int front, rear;
} Queue;
// Function to initialize the queue
void initializeQueue(Queue *q) {
    q->front = -1;
    q->rear = -1;
}
// Function to check if the queue is empty
int isEmpty(Queue *q) {
    return q->front == -1;
}
// Function to check if the queue is full
int isFull(Queue *q) {
    return q->rear == MAX - 1;
}
// Function to add an element to the queue
void enqueue(Queue *q, int value) {
    if (isFull(q)) {
        printf("Queue is full!\n");
    } else {
        if (q->front == -1) {
            q->front = 0;
        }
        q->rear++;
        q->items[q->rear] = value;
    }
}
// Function to remove an element from the queue
int dequeue(Queue *q) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return -1;
    } else {
        int item = q->items[q->front];
        if (q->front == q->rear) {
            q->front = q->rear = -1;
        } else {
            q->front++;
        }
        return item;
    }
}
// Function to implement the Josephus problem using a queue
int josephus(Queue *q, int n, int k) {
    // Enqueue all people to the queue
    for (int i = 1; i <= n; i++) {
        enqueue(q, i);
    }
    // Loop to remove every k-th person
    while (q->rear > q->front) {
        // Skip k-1 people
        for (int i = 1; i < k; i++) {
            int person = dequeue(q);
            enqueue(q, person);
        }
        // Remove the k-th person
        dequeue(q);
    }
    // The last person remaining is the survivor
    return q->items[q->front];
}
int main() {
    int n, k;
    // Take input from the user
    printf("Enter the number of people (n): ");
    scanf("%d", &n);
    printf("Enter the step count (k): ");
    scanf("%d", &k);
    Queue q;
    initializeQueue(&q);
    // Calculate and display the survivor
    int survivor = josephus(&q, n, k);
    printf("The position of the last survivor is: %d\n", survivor);
    return 0;
}
Q40 -Write a menu driven program to create a Binary Tree and
perform following non-recursive operations on it.
  1. Preorder traversal, 2. Display mirror image of a tree without
     creating new tree, 3. Display height of a tree.
Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
  int data;
  struct Node *left, *right;
} Node;
// Stack structure for iterative traversal
typedef struct Stack {
  Node *data;
  struct Stack *next;
} Stack;
// Function to create a new tree node
Node* createNode(int data) {
  Node newNode = (Node)malloc(sizeof(Node));
  newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to push node into stack
void push(Stack **top, Node *node) {
    Stack newNode = (Stack)malloc(sizeof(Stack));
    newNode->data = node;
    newNode->next = *top;
    *top = newNode;
}
// Function to pop node from stack
Node* pop(Stack **top) {
    if (*top == NULL) return NULL;
    Stack *temp = *top;
    *top = (*top)->next;
    Node *node = temp->data;
    free(temp);
    return node;
}
// Function to check if stack is empty
int isEmpty(Stack *top) {
    return top == NULL;
}
// Insert node in binary tree
Node* insertNode(Node *root, int data) {
    if (root == NULL) return createNode(data);
    char direction;
  printf("Enter 'L' to insert to left or 'R' to insert to right of %d: ",
root->data);
    scanf(" %c", &direction);
  if (direction == 'L' || direction == 'l') root->left = insertNode(root-
>left, data);
    else root->right = insertNode(root->right, data);
    return root;
}
// Non-recursive Preorder traversal
void preorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack = NULL;
    push(&stack, root);
    while (!isEmpty(stack)) {
      root = pop(&stack);
      printf("%d ", root->data);
        if (root->right) push(&stack, root->right);
        if (root->left) push(&stack, root->left);
    }
    printf("\n");
}
// Display mirror image of tree (in-place without creating a new tree)
void mirrorImage(Node *root) {
    if (root == NULL) return;
    Stack *stack = NULL;
    push(&stack, root);
    while (!isEmpty(stack)) {
        root = pop(&stack);
        Node *temp = root->left;
        root->left = root->right;
        root->right = temp;
        if (root->right) push(&stack, root->right);
        if (root->left) push(&stack, root->left);
    }
}
// Calculate the height of the tree
int heightOfTree(Node *root) {
    if (root == NULL) return 0;
    Stack *stack = NULL, *heightStack = NULL;
    push(&stack, root);
    push(&heightStack, (Node*)1); // Push initial height as 1
    int maxHeight = 0;
    while (!isEmpty(stack)) {
        root = pop(&stack);
        int currentHeight = (int)(long)pop(&heightStack); // Cast back to
int
        if (currentHeight > maxHeight) maxHeight = currentHeight;
        if (root->right) {
            push(&stack, root->right);
            push(&heightStack, (Node*)(long)(currentHeight + 1));
        }
        if (root->left) {
            push(&stack, root->left);
            push(&heightStack, (Node*)(long)(currentHeight + 1));
        }
    }
    return maxHeight;
}
// Menu-driven program to perform operations
int main() {
  Node *root = NULL;
  int choice, data;
  while (1) {
    printf("\nMenu:\n");
    printf("1. Insert a node\n");
    printf("2. Preorder traversal\n");
    printf("3. Display mirror image of the tree\n");
    printf("4. Display height of the tree\n");
    printf("5. Exit\n");
    printf("Enter your choice: ");
    scanf("%d", &choice);
    switch (choice) {
       case 1:
         printf("Enter data to insert: ");
         scanf("%d", &data);
         if (root == NULL) root = createNode(data);
         else root = insertNode(root, data);
         break;
       case 2:
         printf("Preorder traversal: ");
              preorderTraversal(root);
              break;
            case 3:
              mirrorImage(root);
              printf("Mirror image displayed (original tree modified).\n");
              break;
            case 4:
              printf("Height of the tree: %d\n", heightOfTree(root));
              break;
            case 5:
              exit(0);
              break;
            default:
              printf("Invalid choice! Please enter again.\n");
              break;
        }
    }
    return 0;
}
Q41 -Write a menu driven program to create a Binary Tree and
perform following non-recursive operations on it.
 1. Postorder Traversal, 2. Display a tree levelwise, 3. Display leaf
nodes of a tree.
Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
  int data;
  struct Node *left, *right;
} Node;
typedef struct Queue {
  Node *data;
  struct Queue *next;
} Queue;
// Function to create a new tree node
Node* createNode(int data) {
  Node newNode = (Node)malloc(sizeof(Node));
  newNode->data = data;
  newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to enqueue node to the queue
void enqueue(Queue **front, Queue **rear, Node *node) {
    Queue newNode = (Queue)malloc(sizeof(Queue));
    newNode->data = node;
    newNode->next = NULL;
    if (*rear) (*rear)->next = newNode;
    *rear = newNode;
    if (!*front) *front = *rear;
}
// Function to dequeue node from the queue
Node* dequeue(Queue **front) {
    if (!*front) return NULL;
    Queue *temp = *front;
    *front = (*front)->next;
    if (!*front) *rear = NULL;
    Node *node = temp->data;
    free(temp);
    return node;
}
// Stack structure for postorder traversal
typedef struct Stack {
    Node *data;
    struct Stack *next;
} Stack;
// Function to push a node onto the stack
void push(Stack **top, Node *node) {
    Stack newNode = (Stack)malloc(sizeof(Stack));
    newNode->data = node;
    newNode->next = *top;
    *top = newNode;
}
// Function to pop a node from the stack
Node* pop(Stack **top) {
    if (*top == NULL) return NULL;
    Stack *temp = *top;
    *top = (*top)->next;
    Node *node = temp->data;
    free(temp);
    return node;
}
// Function to check if the stack is empty
int isStackEmpty(Stack *top) {
    return top == NULL;
}
// Insert node in binary tree
Node* insertNode(Node *root, int data) {
    if (root == NULL) return createNode(data);
    char direction;
  printf("Enter 'L' to insert to left or 'R' to insert to right of %d: ",
root->data);
    scanf(" %c", &direction);
  if (direction == 'L' || direction == 'l') root->left = insertNode(root-
>left, data);
    else root->right = insertNode(root->right, data);
    return root;
}
// Non-recursive Postorder traversal
void postorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack1 = NULL, *stack2 = NULL;
    push(&stack1, root);
    while (!isStackEmpty(stack1)) {
        Node *node = pop(&stack1);
        push(&stack2, node);
        if (node->left) push(&stack1, node->left);
        if (node->right) push(&stack1, node->right);
    }
    while (!isStackEmpty(stack2)) {
        Node *node = pop(&stack2);
        printf("%d ", node->data);
    }
    printf("\n");
}
// Display tree levelwise
void displayLevelwise(Node *root) {
    if (root == NULL) return;
    Queue *front = NULL, *rear = NULL;
    enqueue(&front, &rear, root);
    while (front) {
        Node *node = dequeue(&front);
        printf("%d ", node->data);
        if (node->left) enqueue(&front, &rear, node->left);
        if (node->right) enqueue(&front, &rear, node->right);
    }
    printf("\n");
}
// Display leaf nodes
void displayLeafNodes(Node *root) {
    if (root == NULL) return;
    Stack *stack = NULL;
    push(&stack, root);
    while (!isStackEmpty(stack)) {
        Node *node = pop(&stack);
        if (!node->left && !node->right) {
            printf("%d ", node->data);
        }
        if (node->right) push(&stack, node->right);
        if (node->left) push(&stack, node->left);
    }
    printf("\n");
}
// Menu-driven program to perform operations
int main() {
  Node *root = NULL;
  int choice, data;
  while (1) {
    printf("\nMenu:\n");
    printf("1. Insert a node\n");
    printf("2. Postorder traversal\n");
    printf("3. Display tree levelwise\n");
    printf("4. Display leaf nodes\n");
    printf("5. Exit\n");
    printf("Enter your choice: ");
    scanf("%d", &choice);
    switch (choice) {
       case 1:
         printf("Enter data to insert: ");
         scanf("%d", &data);
         if (root == NULL) root = createNode(data);
         else root = insertNode(root, data);
         break;
       case 2:
         printf("Postorder traversal: ");
              postorderTraversal(root);
              break;
            case 3:
              printf("Tree levelwise: ");
              displayLevelwise(root);
              break;
            case 4:
              printf("Leaf nodes: ");
              displayLeafNodes(root);
              break;
            case 5:
              exit(0);
              break;
            default:
              printf("Invalid choice! Please enter again.\n");
              break;
        }
    }
    return 0;
}
Q42-Write a menu driven program to create a Binary Tree and
perform following non-recursive operations on it.
  1. Inorder Traversal, 2. Display mirror image of a tree by creating
new tree, 3. Equality of two trees.
Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
    int data;
    struct Node *left, *right;
} Node;
// Stack structure for iterative traversal
typedef struct Stack {
    Node* nodes[100];
    int top;
} Stack;
void initStack(Stack *s) {
    s->top = -1;
}
int isStackEmpty(Stack *s) {
    return s->top == -1;
}
void push(Stack *s, Node *node) {
    s->nodes[++(s->top)] = node;
}
Node* pop(Stack *s) {
    return s->nodes[(s->top)--];
}
// Function to create a new node
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}
// Insert a node into the Binary Tree
Node* insert(Node* root, int data) {
    if (!root)
      return createNode(data);
    if (data < root->data)
      root->left = insert(root->left, data);
    else if (data > root->data)
      root->right = insert(root->right, data);
    return root;
}
// Inorder Traversal (Non-Recursive)
void inorderTraversal(Node* root) {
    Stack stack;
    initStack(&stack);
    Node* curr = root;
    while (curr != NULL || !isStackEmpty(&stack)) {
      while (curr != NULL) {
          push(&stack, curr);
          curr = curr->left;
      }
      curr = pop(&stack);
      printf("%d ", curr->data);
      curr = curr->right;
    }
    printf("\n");
}
// Mirror Image of the Tree
Node* mirrorTree(Node* root) {
    if (!root)
        return NULL;
    Node* mirrorRoot = createNode(root->data);
    mirrorRoot->left = mirrorTree(root->right);
    mirrorRoot->right = mirrorTree(root->left);
    return mirrorRoot;
}
// Check Equality of Two Trees (Non-Recursive)
int areEqual(Node* root1, Node* root2) {
    Stack stack1, stack2;
    initStack(&stack1);
    initStack(&stack2);
    push(&stack1, root1);
    push(&stack2, root2);
    while (!isStackEmpty(&stack1) && !isStackEmpty(&stack2)) {
        Node* node1 = pop(&stack1);
        Node* node2 = pop(&stack2);
        if (node1 == NULL && node2 == NULL)
          continue;
   if ((node1 == NULL || node2 == NULL) || (node1->data !=
node2->data))
          return 0;
        push(&stack1, node1->right);
        push(&stack1, node1->left);
        push(&stack2, node2->right);
        push(&stack2, node2->left);
    }
    return isStackEmpty(&stack1) && isStackEmpty(&stack2);
}
int main() {
    Node *root = NULL, *mirrorRoot = NULL;
    int choice, data, result;
do {
  printf("\nMenu:\n");
  printf("1. Inorder Traversal\n");
  printf("2. Display Mirror Image of the Tree\n");
  printf("3. Check Equality of Two Trees\n");
  printf("4. Insert a Node\n");
  printf("5. Exit\n");
  printf("Enter your choice: ");
  scanf("%d", &choice);
  switch (choice) {
       case 1:
         printf("Inorder Traversal: ");
         inorderTraversal(root);
         break;
       case 2:
         mirrorRoot = mirrorTree(root);
         printf("Mirror Image (Inorder Traversal): ");
         inorderTraversal(mirrorRoot);
         break;
       case 3: {
         Node *secondTree = NULL;
         printf("Enter elements of second tree (-1 to stop): ");
              while (1) {
                  scanf("%d", &data);
                  if (data == -1) break;
                  secondTree = insert(secondTree, data);
              }
              result = areEqual(root, secondTree);
              printf("The trees are %s.\n", result ? "equal" : "not equal");
              break;
          }
          case 4:
              printf("Enter data to insert: ");
              scanf("%d", &data);
              root = insert(root, data);
              break;
          case 5:
              printf("Exiting...\n");
              break;
          default:
              printf("Invalid choice! Please try again.\n");
      }
    } while (choice != 5);
    return 0;
}
Q 43-Write a menu driven program to create a Binary Tree and
perform following non-recursive operations on it.
 1. Postorder Traversal, 2. Preorder Traversal, 3. Copy a tree.
Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
  int data;
  struct Node *left, *right;
} Node;
// Stack structure for iterative traversals
typedef struct Stack {
  Node *data;
  struct Stack *next;
} Stack;
// Function to create a new tree node
Node* createNode(int data) {
  Node newNode = (Node)malloc(sizeof(Node));
  newNode->data = data;
  newNode->left = newNode->right = NULL;
  return newNode;
}
// Function to push a node onto the stack
void push(Stack **top, Node *node) {
    Stack newNode = (Stack)malloc(sizeof(Stack));
    newNode->data = node;
    newNode->next = *top;
    *top = newNode;
}
// Function to pop a node from the stack
Node* pop(Stack **top) {
    if (*top == NULL) return NULL;
    Stack *temp = *top;
    *top = (*top)->next;
    Node *node = temp->data;
    free(temp);
    return node;
}
// Function to check if the stack is empty
int isStackEmpty(Stack *top) {
    return top == NULL;
}
// Insert node in binary tree
Node* insertNode(Node *root, int data) {
    if (root == NULL) return createNode(data);
    char direction;
  printf("Enter 'L' to insert to left or 'R' to insert to right of %d: ",
root->data);
    scanf(" %c", &direction);
  if (direction == 'L' || direction == 'l') root->left = insertNode(root-
>left, data);
    else root->right = insertNode(root->right, data);
    return root;
}
// Non-recursive Postorder Traversal
void postorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack1 = NULL, *stack2 = NULL;
    push(&stack1, root);
    while (!isStackEmpty(stack1)) {
      Node *node = pop(&stack1);
      push(&stack2, node);
      if (node->left) push(&stack1, node->left);
        if (node->right) push(&stack1, node->right);
    }
    while (!isStackEmpty(stack2)) {
        Node *node = pop(&stack2);
        printf("%d ", node->data);
    }
    printf("\n");
}
// Non-recursive Preorder Traversal
void preorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack = NULL;
    push(&stack, root);
    while (!isStackEmpty(stack)) {
        root = pop(&stack);
        printf("%d ", root->data);
        if (root->right) push(&stack, root->right);
        if (root->left) push(&stack, root->left);
    }
    printf("\n");
}
// Non-recursive Copy of a Binary Tree
Node* copyTree(Node *root) {
  if (root == NULL) return NULL;
  Stack *stackOriginal = NULL, *stackCopy = NULL;
  Node *rootCopy = createNode(root->data);
  push(&stackOriginal, root);
  push(&stackCopy, rootCopy);
  while (!isStackEmpty(stackOriginal)) {
      Node *nodeOriginal = pop(&stackOriginal);
      Node *nodeCopy = pop(&stackCopy);
      if (nodeOriginal->left) {
          nodeCopy->left = createNode(nodeOriginal->left->data);
          push(&stackOriginal, nodeOriginal->left);
          push(&stackCopy, nodeCopy->left);
      }
      if (nodeOriginal->right) {
          nodeCopy->right = createNode(nodeOriginal->right->data);
          push(&stackOriginal, nodeOriginal->right);
          push(&stackCopy, nodeCopy->right);
      }
  }
    return rootCopy;
}
// In-order Traversal to display the tree (to verify copy)
void inorderTraversal(Node *root) {
    if (root == NULL) return;
    inorderTraversal(root->left);
    printf("%d ", root->data);
    inorderTraversal(root->right);
}
// Menu-driven program to perform operations
int main() {
    Node *root = NULL, *rootCopy = NULL;
    int choice, data;
    while (1) {
      printf("\nMenu:\n");
      printf("1. Insert a node\n");
      printf("2. Postorder traversal\n");
      printf("3. Preorder traversal\n");
      printf("4. Copy the tree\n");
      printf("5. Display inorder traversal of copied tree\n");
printf("6. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
  case 1:
    printf("Enter data to insert: ");
    scanf("%d", &data);
    if (root == NULL) root = createNode(data);
    else root = insertNode(root, data);
    break;
  case 2:
    printf("Postorder traversal: ");
    postorderTraversal(root);
    break;
  case 3:
    printf("Preorder traversal: ");
    preorderTraversal(root);
    break;
  case 4:
    rootCopy = copyTree(root);
              printf("Tree copied successfully.\n");
              break;
            case 5:
              if (rootCopy) {
                  printf("Inorder traversal of copied tree: ");
                  inorderTraversal(rootCopy);
                  printf("\n");
              } else {
                  printf("Tree has not been copied yet.\n");
              }
              break;
            case 6:
              exit(0);
              break;
            default:
              printf("Invalid choice! Please enter again.\n");
              break;
        }
    }
    return 0;
}
Q44 -Write a menu driven program to create a Binary Search Tree
and perform following non-recursive operations on it.
  1. Preorder traversal, 2. Display mirror image of a tree without
creating new tree, 3. Display height of a tree.
Code:
#include <stdio.h>
#include <stdlib.h>
// Define the structure for the node
typedef struct Node {
    int data;
    struct Node *left, *right;
} Node;
// Stack structure for non-recursive traversal
typedef struct Stack {
    Node* nodes[100];
    int top;
} Stack;
void initStack(Stack *s) {
    s->top = -1;
}
int isStackEmpty(Stack *s) {
    return s->top == -1;
}
void push(Stack *s, Node *node) {
    s->nodes[++(s->top)] = node;
}
Node* pop(Stack *s) {
    return s->nodes[(s->top)--];
}
// Function to create a new node
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to insert a node into the BST
Node* insert(Node* root, int data) {
    if (root == NULL) return createNode(data);
    Node *current = root, *parent = NULL;
    while (current != NULL) {
        parent = current;
        if (data < current->data)
           current = current->left;
        else
           current = current->right;
    }
    if (data < parent->data)
        parent->left = createNode(data);
    else
        parent->right = createNode(data);
    return root;
}
// Non-recursive Preorder Traversal
void preorderTraversal(Node* root) {
    if (root == NULL) return;
    Stack s;
    initStack(&s);
    push(&s, root);
    while (!isStackEmpty(&s)) {
        Node *current = pop(&s);
        printf("%d ", current->data);
        if (current->right) push(&s, current->right);
        if (current->left) push(&s, current->left);
    }
    printf("\n");
}
// Function to mirror the tree (swap left and right child)
void mirrorTree(Node* root) {
    if (root == NULL) return;
    Stack s;
    initStack(&s);
    push(&s, root);
    while (!isStackEmpty(&s)) {
        Node* current = pop(&s);
        Node* temp = current->left;
        current->left = current->right;
        current->right = temp;
        if (current->left) push(&s, current->left);
        if (current->right) push(&s, current->right);
    }
}
// Function to calculate the height of the tree
int treeHeight(Node* root) {
if (root == NULL) return 0;
Stack s;
int maxDepth = 0;
struct {
    Node* node;
    int depth;
} nodeInfo[100];
int top = 0;
nodeInfo[top].node = root;
nodeInfo[top].depth = 1;
while (top >= 0) {
    Node* current = nodeInfo[top].node;
    int depth = nodeInfo[top--].depth;
    if (depth > maxDepth) maxDepth = depth;
    if (current->left) {
        nodeInfo[++top].node = current->left;
        nodeInfo[top].depth = depth + 1;
    }
    if (current->right) {
        nodeInfo[++top].node = current->right;
        nodeInfo[top].depth = depth + 1;
    }
}
return maxDepth;
}
// Menu-driven program
int main() {
    Node* root = NULL;
    int choice, data;
    do {
      printf("\nBinary Search Tree Operations:\n");
      printf("1. Insert\n");
      printf("2. Preorder Traversal\n");
      printf("3. Display Mirror Image (In-place)\n");
      printf("4. Display Height of the Tree\n");
      printf("5. Exit\n");
      printf("Enter your choice: ");
      scanf("%d", &choice);
      switch (choice) {
           case 1:
             printf("Enter data to insert: ");
             scanf("%d", &data);
             root = insert(root, data);
             break;
           case 2:
             printf("Preorder Traversal: ");
            preorderTraversal(root);
            break;
          case 3:
            printf("Displaying mirror image of the tree...\n");
            mirrorTree(root);
            printf("Tree mirrored.\n");
            break;
          case 4:
            printf("Height of the Tree: %d\n", treeHeight(root));
            break;
          case 5:
            printf("Exiting...\n");
            break;
          default:
            printf("Invalid choice! Please try again.\n");
            break;
      }
    } while (choice != 5);
    return 0;
}
Q45 Write a menu driven program to create a Binary Search Tree
and perform following non-recursive operations on it.
 1. Postorder Traversal, 2. Display a tree levelwise, 3. Display leaf
nodes of a tree.
Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
  int data;
  struct Node *left, *right;
} Node;
// Queue structure for levelwise display
typedef struct Queue {
  Node *data;
  struct Queue *next;
} Queue;
// Stack structure for postorder traversal
typedef struct Stack {
  Node *data;
  struct Stack *next;
} Stack;
// Function to create a new tree node
Node* createNode(int data) {
    Node newNode = (Node)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to insert a node in the Binary Search Tree
Node* insertNode(Node *root, int data) {
    if (root == NULL) return createNode(data);
    if (data < root->data) root->left = insertNode(root->left, data);
  else if (data > root->data) root->right = insertNode(root->right,
data);
    return root;
}
// Function to enqueue a node to the queue
void enqueue(Queue **front, Queue **rear, Node *node) {
    Queue newNode = (Queue)malloc(sizeof(Queue));
    newNode->data = node;
    newNode->next = NULL;
    if (*rear) (*rear)->next = newNode;
    *rear = newNode;
    if (*front == NULL) *front = *rear;
}
// Function to dequeue a node from the queue
Node* dequeue(Queue **front) {
    if (*front == NULL) return NULL;
    Queue *temp = *front;
    *front = (*front)->next;
    Node *node = temp->data;
    free(temp);
    return node;
}
// Function to check if the queue is empty
int isQueueEmpty(Queue *front) {
    return front == NULL;
}
// Function to push a node to the stack
void push(Stack **top, Node *node) {
    Stack newNode = (Stack)malloc(sizeof(Stack));
    newNode->data = node;
    newNode->next = *top;
    *top = newNode;
}
// Function to pop a node from the stack
Node* pop(Stack **top) {
    if (*top == NULL) return NULL;
    Stack *temp = *top;
    *top = (*top)->next;
    Node *node = temp->data;
    free(temp);
    return node;
}
// Function to check if the stack is empty
int isStackEmpty(Stack *top) {
    return top == NULL;
}
// Non-recursive Postorder Traversal
void postorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack1 = NULL, *stack2 = NULL;
    push(&stack1, root);
    while (!isStackEmpty(stack1)) {
        Node *node = pop(&stack1);
        push(&stack2, node);
        if (node->left) push(&stack1, node->left);
        if (node->right) push(&stack1, node->right);
    }
    while (!isStackEmpty(stack2)) {
        Node *node = pop(&stack2);
        printf("%d ", node->data);
    }
    printf("\n");
}
// Display tree levelwise using Queue
void displayLevelwise(Node *root) {
    if (root == NULL) return;
    Queue *front = NULL, *rear = NULL;
    enqueue(&front, &rear, root);
    while (!isQueueEmpty(front)) {
        Node *node = dequeue(&front);
        printf("%d ", node->data);
        if (node->left) enqueue(&front, &rear, node->left);
        if (node->right) enqueue(&front, &rear, node->right);
    }
    printf("\n");
}
// Display leaf nodes
void displayLeafNodes(Node *root) {
    if (root == NULL) return;
    Stack *stack = NULL;
    push(&stack, root);
    while (!isStackEmpty(stack)) {
        Node *node = pop(&stack);
        if (!node->left && !node->right) {
          printf("%d ", node->data);
        }
        if (node->right) push(&stack, node->right);
        if (node->left) push(&stack, node->left);
    }
    printf("\n");
}
// Menu-driven program to perform operations
int main() {
    Node *root = NULL;
    int choice, data;
    while (1) {
        printf("\nMenu:\n");
        printf("1. Insert a node\n");
        printf("2. Postorder traversal\n");
        printf("3. Display tree levelwise\n");
        printf("4. Display leaf nodes\n");
        printf("5. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
case 1:
  printf("Enter data to insert: ");
  scanf("%d", &data);
  if (root == NULL) root = createNode(data);
  else root = insertNode(root, data);
  break;
case 2:
  printf("Postorder traversal: ");
  postorderTraversal(root);
  break;
case 3:
  printf("Tree levelwise: ");
  displayLevelwise(root);
  break;
case 4:
  printf("Leaf nodes: ");
  displayLeafNodes(root);
  break;
case 5:
  exit(0);
              break;
            default:
              printf("Invalid choice! Please enter again.\n");
              break;
        }
    }
    return 0;
}
Q46 -Write a menu driven program to create a Binary Search Tree
and perform following non-recursive operations on it.
  1. Inorder Traversal, 2. Display mirror image of a tree by creating
new tree, 3. Delete a node from a tree.
Code:
#include <stdio.h>
#include <stdlib.h>
// Define the structure for the node
typedef struct Node {
    int data;
    struct Node *left, *right;
} Node;
// Stack structure for non-recursive traversal
typedef struct Stack {
    Node* nodes[100];
    int top;
} Stack;
void initStack(Stack *s) {
    s->top = -1;
}
int isStackEmpty(Stack *s) {
    return s->top == -1;
}
void push(Stack *s, Node *node) {
    s->nodes[++(s->top)] = node;
}
Node* pop(Stack *s) {
    return s->nodes[(s->top)--];
}
// Function to create a new node
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to insert a node into the BST
Node* insert(Node* root, int data) {
    if (root == NULL) return createNode(data);
    Node *current = root, *parent = NULL;
    while (current != NULL) {
        parent = current;
        if (data < current->data)
           current = current->left;
        else
           current = current->right;
    }
    if (data < parent->data)
        parent->left = createNode(data);
    else
        parent->right = createNode(data);
    return root;
}
// Non-recursive Inorder Traversal
void inorderTraversal(Node* root) {
    if (root == NULL) return;
    Stack s;
    initStack(&s);
    Node* current = root;
    while (current != NULL || !isStackEmpty(&s)) {
        while (current != NULL) {
           push(&s, current);
            current = current->left;
        }
        current = pop(&s);
        printf("%d ", current->data);
        current = current->right;
    }
    printf("\n");
}
// Function to create a mirror image of the tree
Node* mirrorTree(Node* root) {
    if (root == NULL) return NULL;
    Node* newRoot = createNode(root->data);
    Stack s;
    initStack(&s);
    push(&s, root);
    Node* current = newRoot;
    while (!isStackEmpty(&s)) {
        current = pop(&s);
        if (current->left) {
            current->right = createNode(current->left->data);
            push(&s, current->left);
        }
        if (current->right) {
            current->left = createNode(current->right->data);
            push(&s, current->right);
        }
    }
    return newRoot;
}
// Function to delete a node from the BST
Node* deleteNode(Node* root, int data) {
    if (root == NULL) return root;
    // Find the node to be deleted
    if (data < root->data) {
        root->left = deleteNode(root->left, data);
    } else if (data > root->data) {
        root->right = deleteNode(root->right, data);
    } else {
        // Node to be deleted found
        // Case 1: No children (leaf node)
        if (root->left == NULL && root->right == NULL) {
            free(root);
            root = NULL;
        }
        // Case 2: One child
    else if (root->left == NULL) {
        Node* temp = root;
        root = root->right;
        free(temp);
    } else if (root->right == NULL) {
        Node* temp = root;
        root = root->left;
        free(temp);
    }
    // Case 3: Two children
    else {
        // Find the inorder successor (smallest in the right subtree)
        Node* temp = root->right;
        while (temp && temp->left != NULL)
          temp = temp->left;
        // Copy the inorder successor's content to this node
        root->data = temp->data;
        // Delete the inorder successor
        root->right = deleteNode(root->right, temp->data);
    }
}
return root;
}
// Menu-driven program
int main() {
    Node* root = NULL;
    int choice, data;
    do {
      printf("\nBinary Search Tree Operations:\n");
      printf("1. Insert\n");
      printf("2. Inorder Traversal\n");
      printf("3. Display Mirror Image of the Tree (New Tree)\n");
      printf("4. Delete a Node\n");
      printf("5. Exit\n");
      printf("Enter your choice: ");
      scanf("%d", &choice);
      switch (choice) {
           case 1:
             printf("Enter data to insert: ");
             scanf("%d", &data);
             root = insert(root, data);
             break;
           case 2:
             printf("Inorder Traversal: ");
            inorderTraversal(root);
            break;
          case 3:
            printf("Displaying mirror image of the tree...\n");
            Node* mirror = mirrorTree(root);
            printf("Mirror Image (In-order): ");
            inorderTraversal(mirror);
            break;
          case 4:
            printf("Enter data to delete: ");
            scanf("%d", &data);
            root = deleteNode(root, data);
            break;
          case 5:
            printf("Exiting...\n");
            break;
          default:
            printf("Invalid choice! Please try again.\n");
            break;
      }
    } while (choice != 5);
    return 0;
}
Q47 -Write a menu driven program to create a Binary Search Tree
and perform following non-recursive operations on it.
 1. Postorder Traversal, 2. Preorder Traversal, 3. Inorder Traversal.
Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
  int data;
  struct Node *left, *right;
} Node;
// Stack structure for iterative traversals
typedef struct Stack {
  Node *data;
  struct Stack *next;
} Stack;
// Function to create a new tree node
Node* createNode(int data) {
  Node newNode = (Node)malloc(sizeof(Node));
  newNode->data = data;
  newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to insert a node in the Binary Search Tree
Node* insertNode(Node *root, int data) {
    if (root == NULL) return createNode(data);
    if (data < root->data) root->left = insertNode(root->left, data);
  else if (data > root->data) root->right = insertNode(root->right,
data);
    return root;
}
// Function to push a node onto the stack
void push(Stack **top, Node *node) {
    Stack newNode = (Stack)malloc(sizeof(Stack));
    newNode->data = node;
    newNode->next = *top;
    *top = newNode;
}
// Function to pop a node from the stack
Node* pop(Stack **top) {
    if (*top == NULL) return NULL;
    Stack *temp = *top;
    *top = (*top)->next;
    Node *node = temp->data;
    free(temp);
    return node;
}
// Function to check if the stack is empty
int isStackEmpty(Stack *top) {
    return top == NULL;
}
// Non-recursive Postorder Traversal
void postorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack1 = NULL, *stack2 = NULL;
    push(&stack1, root);
    while (!isStackEmpty(stack1)) {
      Node *node = pop(&stack1);
      push(&stack2, node);
        if (node->left) push(&stack1, node->left);
        if (node->right) push(&stack1, node->right);
    }
    while (!isStackEmpty(stack2)) {
        Node *node = pop(&stack2);
        printf("%d ", node->data);
    }
    printf("\n");
}
// Non-recursive Preorder Traversal
void preorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack = NULL;
    push(&stack, root);
    while (!isStackEmpty(stack)) {
        Node *node = pop(&stack);
        printf("%d ", node->data);
        if (node->right) push(&stack, node->right);
        if (node->left) push(&stack, node->left);
    }
    printf("\n");
}
// Non-recursive Inorder Traversal
void inorderTraversal(Node *root) {
    if (root == NULL) return;
    Stack *stack = NULL;
    Node *current = root;
    while (current != NULL || !isStackEmpty(stack)) {
        while (current != NULL) {
            push(&stack, current);
            current = current->left;
        }
        current = pop(&stack);
        printf("%d ", current->data);
        current = current->right;
    }
    printf("\n");
}
// Menu-driven program to perform operations
int main() {
  Node *root = NULL;
  int choice, data;
  while (1) {
    printf("\nMenu:\n");
    printf("1. Insert a node\n");
    printf("2. Postorder traversal\n");
    printf("3. Preorder traversal\n");
    printf("4. Inorder traversal\n");
    printf("5. Exit\n");
    printf("Enter your choice: ");
    scanf("%d", &choice);
    switch (choice) {
       case 1:
         printf("Enter data to insert: ");
         scanf("%d", &data);
         if (root == NULL) root = createNode(data);
         else root = insertNode(root, data);
         break;
        case 2:
          printf("Postorder traversal: ");
          postorderTraversal(root);
          break;
        case 3:
          printf("Preorder traversal: ");
          preorderTraversal(root);
          break;
        case 4:
          printf("Inorder traversal: ");
          inorderTraversal(root);
          break;
        case 5:
          exit(0);
          break;
        default:
          printf("Invalid choice! Please enter again.\n");
          break;
    }
}
    return 0;
}
Q48 Write a menu driven program to create a Binary Search Tree
and perform following non-recursive operations on it.
1. Copy a tree, 2. Equality of two trees, 3. Delete a node from a
tree.
Code:
#include <stdio.h>
#include <stdlib.h>
// Define the structure for the node
typedef struct Node {
    int data;
    struct Node *left, *right;
} Node;
// Stack structure for non-recursive traversal
typedef struct Stack {
    Node* nodes[100];
    int top;
} Stack;
void initStack(Stack *s) {
    s->top = -1;
}
int isStackEmpty(Stack *s) {
    return s->top == -1;
}
void push(Stack *s, Node *node) {
    s->nodes[++(s->top)] = node;
}
Node* pop(Stack *s) {
    return s->nodes[(s->top)--];
}
// Function to create a new node
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to insert a node into the BST
Node* insert(Node* root, int data) {
    if (root == NULL) return createNode(data);
    Node *current = root, *parent = NULL;
    while (current != NULL) {
        parent = current;
        if (data < current->data)
           current = current->left;
        else
           current = current->right;
    }
    if (data < parent->data)
        parent->left = createNode(data);
    else
        parent->right = createNode(data);
    return root;
}
// Non-recursive function to copy a tree
Node* copyTree(Node* root) {
    if (root == NULL) return NULL;
    Node* newRoot = createNode(root->data);
    Stack s1, s2;
    initStack(&s1);
    initStack(&s2);
    push(&s1, root);
    push(&s2, newRoot);
    while (!isStackEmpty(&s1)) {
        Node *currentOriginal = pop(&s1);
        Node *currentCopy = pop(&s2);
        if (currentOriginal->left) {
            currentCopy->left = createNode(currentOriginal->left->data);
            push(&s1, currentOriginal->left);
            push(&s2, currentCopy->left);
        }
        if (currentOriginal->right) {
      currentCopy->right = createNode(currentOriginal->right-
>data);
            push(&s1, currentOriginal->right);
            push(&s2, currentCopy->right);
        }
    }
    return newRoot;
}
// Non-recursive function to check equality of two trees
int areTreesEqual(Node* root1, Node* root2) {
    if (root1 == NULL && root2 == NULL) return 1;
    if (root1 == NULL || root2 == NULL) return 0;
Stack s1, s2;
initStack(&s1);
initStack(&s2);
push(&s1, root1);
push(&s2, root2);
while (!isStackEmpty(&s1)) {
  Node *current1 = pop(&s1);
  Node *current2 = pop(&s2);
  if (current1->data != current2->data) return 0;
  if (current1->left && current2->left) {
      push(&s1, current1->left);
      push(&s2, current2->left);
  } else if (current1->left || current2->left) {
      return 0;
  }
  if (current1->right && current2->right) {
      push(&s1, current1->right);
      push(&s2, current2->right);
  } else if (current1->right || current2->right) {
            return 0;
        }
    }
    return 1;
}
// Non-recursive function to delete a node from the tree
Node* deleteNode(Node* root, int data) {
    if (root == NULL) return root;
    Node* parent = NULL;
    Node* current = root;
    while (current != NULL && current->data != data) {
        parent = current;
        if (data < current->data)
            current = current->left;
        else
            current = current->right;
    }
    if (current == NULL) return root; // Node to delete not found
    // Case 1: Node has no children (leaf node)
    if (current->left == NULL && current->right == NULL) {
    if (parent == NULL) root = NULL; // Deleting root node
    else if (parent->left == current) parent->left = NULL;
    else parent->right = NULL;
    free(current);
}
// Case 2: Node has one child
else if (current->left == NULL || current->right == NULL) {
    Node* child = (current->left) ? current->left : current->right;
    if (parent == NULL) root = child; // Deleting root node
    else if (parent->left == current) parent->left = child;
    else parent->right = child;
    free(current);
}
// Case 3: Node has two children
else {
    Node* successorParent = current;
    Node* successor = current->right;
    while (successor->left != NULL) {
        successorParent = successor;
        successor = successor->left;
    }
    current->data = successor->data;
    if (successorParent->left == successor)
           successorParent->left = successor->right;
        else
           successorParent->right = successor->right;
        free(successor);
    }
    return root;
}
// Menu-driven program
int main() {
    Node* root = NULL;
    int choice, data;
    Node *root2 = NULL;
    do {
        printf("\nBinary Search Tree Operations:\n");
        printf("1. Insert\n");
        printf("2. Copy a Tree\n");
        printf("3. Equality of Two Trees\n");
        printf("4. Delete a Node\n");
        printf("5. Exit\n");
        printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
  case 1:
    printf("Enter data to insert: ");
    scanf("%d", &data);
    root = insert(root, data);
    break;
  case 2:
    printf("Copying the tree...\n");
    Node* copy = copyTree(root);
    printf("Tree copied successfully.\n");
    break;
  case 3:
    printf("Enter data to insert into second tree: ");
    scanf("%d", &data);
    root2 = insert(root2, data);
    if (areTreesEqual(root, root2))
      printf("The trees are equal.\n");
    else
      printf("The trees are not equal.\n");
    break;
  case 4:
    printf("Enter data to delete: ");
            scanf("%d", &data);
            root = deleteNode(root, data);
            printf("Node deleted (if it existed).\n");
            break;
          case 5:
            printf("Exiting...\n");
            break;
          default:
            printf("Invalid choice! Please try again.\n");
            break;
      }
    } while (choice != 5);
    return 0;
}
Q49 -Write a menu driven program to create a Binary Search Tree
and perform following non-recursive operations on it.
1. Insert a node in a tree, 2. Display the height of the tree, 3. Delete
a node from a tree.
Code:
#include <stdio.h>
#include <stdlib.h>
// Definition of Node structure
typedef struct Node {
    int data;
    struct Node *left, *right;
} Node;
// Function to create a new tree node
Node* createNode(int data) {
    Node newNode = (Node)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}
// Function to insert a node in the Binary Search Tree
Node* insertNode(Node *root, int data) {
    Node *newNode = createNode(data);
    if (root == NULL) {
        return newNode;
    }
    Node *parent = NULL, *current = root;
    while (current != NULL) {
        parent = current;
        if (data < current->data) {
            current = current->left;
        } else {
            current = current->right;
        }
    }
    if (data < parent->data) {
        parent->left = newNode;
    } else {
        parent->right = newNode;
    }
    return root;
}
// Function to find the minimum value node in a tree (used for
deleting a node)
Node* findMin(Node *root) {
    while (root->left != NULL) {
        root = root->left;
    }
    return root;
}
// Function to delete a node from the tree
Node* deleteNode(Node *root, int data) {
    if (root == NULL) return root;
    // Find the node to be deleted
    Node *parent = NULL, *current = root;
    while (current != NULL && current->data != data) {
        parent = current;
        if (data < current->data) {
            current = current->left;
        } else {
            current = current->right;
        }
    }
if (current == NULL) return root; // Node not found
// Node with only one child or no child
if (current->left == NULL) {
  if (parent == NULL) {
      root = current->right;
  } else if (parent->left == current) {
      parent->left = current->right;
  } else {
      parent->right = current->right;
  }
} else if (current->right == NULL) {
  if (parent == NULL) {
      root = current->left;
  } else if (parent->left == current) {
      parent->left = current->left;
  } else {
      parent->right = current->left;
  }
} else {
  // Node with two children: Get the inorder successor
  Node *minNode = findMin(current->right);
  current->data = minNode->data;
    root = deleteNode(current->right, minNode->data); // Delete the
inorder successor
    }
    free(current);
    return root;
}
// Function to calculate the height of the tree
int height(Node *root) {
    if (root == NULL) {
        return 0;
    }
    int leftHeight = height(root->left);
    int rightHeight = height(root->right);
    return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
// Menu-driven program to perform operations
int main() {
    Node *root = NULL;
    int choice, data;
while (1) {
  printf("\nMenu:\n");
  printf("1. Insert a node\n");
  printf("2. Display the height of the tree\n");
  printf("3. Delete a node\n");
  printf("4. Exit\n");
  printf("Enter your choice: ");
  scanf("%d", &choice);
  switch (choice) {
    case 1:
       printf("Enter data to insert: ");
       scanf("%d", &data);
       root = insertNode(root, data);
       printf("Node inserted successfully.\n");
       break;
    case 2:
       printf("Height of the tree: %d\n", height(root));
       break;
    case 3:
       printf("Enter data to delete: ");
       scanf("%d", &data);
              root = deleteNode(root, data);
              printf("Node deleted successfully, if it existed.\n");
              break;
            case 4:
              exit(0);
            default:
              printf("Invalid choice! Please enter again.\n");
              break;
        }
    }
    return 0;
}
Q50 -Right Threaded Binary Tree
  Code:
  #include <stdio.h>
  #include <stdlib.h>
  // Structure for Node in Right Threaded Binary Tree
  struct Node {
       int data;
       struct Node* left;
       struct Node* right;
       int leftThread; // 1 if left is a thread, 0 if it's a child
       int rightThread; // 1 if right is a thread, 0 if it's a child
  };
  // Function to create a new Node
  struct Node* createNode(int data) {
   struct Node* newNode = (struct Node*)malloc(sizeof(struct
  Node));
       newNode->data = data;
       newNode->left = newNode->right = NULL;
       newNode->leftThread = newNode->rightThread = 0;
       return newNode;
}
// Function to insert a node in the Right Threaded Binary Tree
struct Node* insert(struct Node* root, int data) {
    if (root == NULL) {
        return createNode(data);
    }
    if (data < root->data) {
        // Insert in left subtree
        if (root->leftThread == 0) {
            root->left = insert(root->left, data);
        } else {
            struct Node* temp = createNode(data);
            temp->left = root->left;
            temp->right = root;
            root->leftThread = 1;
            root->left = temp;
        }
    } else {
        // Insert in right subtree
        if (root->rightThread == 0) {
            root->right = insert(root->right, data);
        } else {
            struct Node* temp = createNode(data);
            temp->right = root->right;
            root->rightThread = 1;
            root->right = temp;
        }
    }
    return root;
}
// Inorder traversal of Right Threaded Binary Tree
void inorder(struct Node* root) {
    struct Node* current = root;
    while (current != NULL) {
        // Move to leftmost node
        while (current->leftThread == 0) {
            current = current->left;
        }
        // Print node data
        printf("%d ", current->data);
        // Move to right node (or successor)
        while (current->rightThread == 1) {
            current = current->right;
            printf("%d ", current->data);
        }
        current = current->right;
    }
}
int main() {
    struct Node* root = NULL;
    int choice, data;
    while (1) {
    printf("\n1. Insert a node into the tree\n2. Display Inorder
Traversal\n3. Exit\nEnter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
            case 1:
              printf("Enter the value to insert: ");
              scanf("%d", &data);
              root = insert(root, data);
              break;
            case 2:
         printf("Inorder traversal of the Right Threaded Binary
Tree:\n");
              inorder(root);
              printf("\n");
              break;
            case 3:
              exit(0);
            default:
              printf("Invalid choice, please try again.\n");
        }
    }
    return 0;
}
Q51-Fully TBST
Code:
#include <stdio.h>
#include <stdlib.h>
// Define a structure for the Threaded Binary Tree (TBT) node
typedef struct TBTNode {
    int data;
    struct TBTNode* left;
    struct TBTNode* right;
    int left_thread; // 1 if left is a thread, 0 if left is a child
    int right_thread; // 1 if right is a thread, 0 if right is a child
} TBTNode;
// Function to create a new node
TBTNode* createNode(int data) {
    TBTNode* newNode = (TBTNode*)malloc(sizeof(TBTNode));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    newNode->left_thread = 0;
    newNode->right_thread = 0;
    return newNode;
}
// Inorder traversal of the Fully Threaded Binary Tree (TBT)
void inorderTraversal(TBTNode* root) {
  // Start from the leftmost node
  TBTNode* current = root;
  while (current != NULL) {
    // Traverse left as long as it's a normal child node
    while (current->left != NULL && current->left_thread == 0) {
        current = current->left;
    }
    // Print the node data
    printf("%d ", current->data);
    // If the right pointer is a thread, follow the thread
    if (current->right_thread == 1) {
        current = current->right;
    } else {
        // Otherwise, move to the right child and go to the leftmost
node
        current = current->right;
      while (current != NULL && current->left_thread == 0 &&
current->left != NULL) {
          current = current->left;
            }
        }
    }
}
// Function to insert a node into the Fully Threaded Binary Tree
(TBT)
TBTNode* insert(TBTNode* root, int data) {
    TBTNode* newNode = createNode(data);
    if (root == NULL) {
        return newNode;
    }
    TBTNode* parent = NULL;
    TBTNode* current = root;
    while (current != NULL) {
        parent = current;
        if (data < current->data) {
            if (current->left == NULL || current->left_thread == 1) {
                break;
            }
            current = current->left;
        } else if (data > current->data) {
            if (current->right == NULL || current->right_thread == 1) {
            break;
        }
        current = current->right;
    }
}
// Insert the new node
if (data < parent->data) {
    parent->left = newNode;
    parent->left_thread = 0;
} else if (data > parent->data) {
    parent->right = newNode;
    parent->right_thread = 0;
}
// Update the threads
if (parent->left != NULL && parent->left_thread == 1) {
    newNode->left = parent->left;
    newNode->left_thread = 1;
}
if (parent->right != NULL && parent->right_thread == 1) {
    newNode->right = parent->right;
    newNode->right_thread = 1;
}
    return root;
}
// Function to prompt the user for input
void interactiveMenu() {
    TBTNode* root = NULL;
    int choice, data;
    while(1) {
      printf("\n--- Fully Threaded Binary Tree ---\n");
      printf("1. Insert Node\n");
      printf("2. Inorder Traversal\n");
      printf("3. Exit\n");
      printf("Enter your choice: ");
      scanf("%d", &choice);
      switch(choice) {
        case 1:
           printf("Enter the data to insert: ");
           scanf("%d", &data);
           root = insert(root, data);
           printf("Node inserted successfully.\n");
           break;
            case 2:
        printf("In-order Traversal of the Fully Threaded Binary
Tree (TBT):\n");
              inorderTraversal(root);
              printf("\n");
              break;
            case 3:
              printf("Exiting...\n");
              return;
            default:
              printf("Invalid choice. Please try again.\n");
        }
    }
}
// Main function
int main() {
    interactiveMenu();
    return 0;
}
Q52-Write a C Program to implement Heap sort using Max heap in
descending order
Code:
#include <stdio.h>
// Function to swap two elements
void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}
// Function to heapify the subtree rooted at index i
void heapify(int arr[], int n, int i) {
    int largest = i; // Initialize largest as root
    int left = 2 * i + 1; // left child index
    int right = 2 * i + 2; // right child index
    // If left child is larger than root
    if (left < n && arr[left] > arr[largest]) {
        largest = left;
    }
    // If right child is larger than largest so far
    if (right < n && arr[right] > arr[largest]) {
        largest = right;
    }
    // If largest is not root
    if (largest != i) {
        swap(&arr[i], &arr[largest]);
        // Recursively heapify the affected sub-tree
        heapify(arr, n, largest);
    }
}
// Function to perform heap sort
void heapSort(int arr[], int n) {
    // Build a max heap
    for (int i = n / 2 - 1; i >= 0; i--) {
        heapify(arr, n, i);
    }
    // One by one extract elements from the heap
    for (int i = n - 1; i > 0; i--) {
        // Move current root to end
        swap(&arr[0], &arr[i]);
        // Call heapify on the reduced heap
        heapify(arr, i, 0);
    }
}
// Function to print an array
void printArray(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}
int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    printf("Original array: \n");
    printArray(arr, n);
    // Perform heap sort
    heapSort(arr, n);
    printf("Sorted array in descending order: \n");
    printArray(arr, n);
    return 0;
}
Q53 Write a C Program to implement Heap sort using Min heap in
ascending order
Code:
#include <stdio.h>
void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}
// Function to heapify the tree at the given index, maintaining the
Min Heap property
void minHeapify(int arr[], int n, int i) {
    int smallest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    // If left child is smaller than root
    if (left < n && arr[left] < arr[smallest])
      smallest = left;
    // If right child is smaller than smallest so far
    if (right < n && arr[right] < arr[smallest])
        smallest = right;
    // If smallest is not root, swap and continue heapifying
    if (smallest != i) {
        swap(&arr[i], &arr[smallest]);
        minHeapify(arr, n, smallest);
    }
}
// Function to build a Min Heap from the given array
void buildMinHeap(int arr[], int n) {
    // Start from the last non-leaf node and heapify each node
    for (int i = n / 2 - 1; i >= 0; i--)
        minHeapify(arr, n, i);
}
// Function to perform Heap Sort in ascending order
void heapSort(int arr[], int n) {
    // Build a Min Heap
    buildMinHeap(arr, n);
    // One by one extract elements from the heap
    for (int i = n - 1; i >= 0; i--) {
        // Move the current root to the end
        swap(&arr[0], &arr[i]);
        // Call minHeapify on the reduced heap
        minHeapify(arr, i, 0);
    }
}
// Function to print the array
void printArray(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}
int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    printf("Original array: ");
    printArray(arr, n);
    heapSort(arr, n);
    printf("Sorted array in ascending order: ");
    printArray(arr, n);
    return 0;
}
Q54-Write a menu driven program to implement Inorder Threaded
Binary tree and traverse it in Inorder, Preorder and Postorder
way.(use inorder threads only)
Code:
#include <stdio.h>
#include <stdlib.h>
// Structure for threaded binary tree node
struct Node {
     int data;
     struct Node *left, *right;
  int rightThread; // 0 if right pointer points to a child, 1 if it points to
the successor
};
// Function to create a new node
struct Node* createNode(int data) {
     struct Node newNode = (struct Node)malloc(sizeof(struct Node));
     newNode->data = data;
     newNode->left = newNode->right = NULL;
     newNode->rightThread = 0;
     return newNode;
}
// Function to perform inorder threading
void inorderThread(struct Node* root, struct Node** prev) {
  if (root == NULL)
      return;
  inorderThread(root->left, prev);
  // If the left child is NULL, set the left pointer to the predecessor
(prev node)
  if (root->left == NULL && *prev != NULL) {
      root->left = *prev;
  }
   // If the right child is NULL, set the right pointer to the successor
(to be threaded)
  if (root->right == NULL && *prev != NULL) {
      root->right = *prev;
      root->rightThread = 1; // Mark this as a thread
  }
  // Move prev to this node
  *prev = root;
  inorderThread(root->right, prev);
}
// Function for inorder traversal using threading
void inorderTraversal(struct Node* root) {
    struct Node* current = root;
    while (current != NULL) {
        // Reach leftmost node
        while (current->left != NULL)
            current = current->left;
        // Print the current node
        printf("%d ", current->data);
        // If there is a thread, go to the successor node
        while (current->rightThread) {
            current = current->right;
            printf("%d ", current->data);
        }
        // Move to the right child
        current = current->right;
    }
}
// Preorder traversal
void preorderTraversal(struct Node* root) {
    if (root == NULL)
        return;
    printf("%d ", root->data);
    if (!root->rightThread) {
        preorderTraversal(root->left);
    }
    preorderTraversal(root->right);
}
// Postorder traversal
void postorderTraversal(struct Node* root) {
    if (root == NULL)
        return;
    postorderTraversal(root->left);
    postorderTraversal(root->right);
    printf("%d ", root->data);
}
// Function to insert nodes in a binary tree (for simplicity, use an in-
order insert)
struct Node* insert(struct Node* root, int data) {
    if (root == NULL)
        return createNode(data);
    if (data < root->data) {
        root->left = insert(root->left, data);
    } else {
        root->right = insert(root->right, data);
    }
    return root;
}
// Menu driven program
int main() {
    struct Node* root = NULL;
    struct Node* prev = NULL;
    int choice, value;
    while (1) {
        printf("\nMenu:\n");
        printf("1. Insert Node\n");
        printf("2. Inorder Traversal\n");
        printf("3. Preorder Traversal\n");
        printf("4. Postorder Traversal\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
  case 1:
    printf("Enter value to insert: ");
    scanf("%d", &value);
    root = insert(root, value);
    inorderThread(root, &prev);
    break;
  case 2:
    printf("Inorder Traversal: ");
    inorderTraversal(root);
    printf("\n");
    break;
  case 3:
    printf("Preorder Traversal: ");
    preorderTraversal(root);
    printf("\n");
    break;
            case 4:
              printf("Postorder Traversal: ");
              postorderTraversal(root);
              printf("\n");
              break;
            case 5:
              exit(0);
            default:
              printf("Invalid choice!\n");
        }
    }
    return 0;
}
Q55-Left Threaded Binary Tree
#include <stdio.h>
#include <stdlib.h>
// Structure for Node in Left Threaded Binary Tree
struct Node {
     int data;
     struct Node* left;
     struct Node* right;
     int leftThread; // 1 if left is a thread, 0 if it's a child
     int rightThread; // 1 if right is a thread, 0 if it's a child
};
// Function to create a new Node
struct Node* createNode(int data) {
 struct Node* newNode = (struct Node*)malloc(sizeof(struct
Node));
     newNode->data = data;
     newNode->left = newNode->right = NULL;
     newNode->leftThread = newNode->rightThread = 0;
     return newNode;
}
// Function to insert a node in the Left Threaded Binary Tree
struct Node* insert(struct Node* root, int data) {
  if (root == NULL) {
      return createNode(data);
  }
  if (data < root->data) {
      // Insert in left subtree
      if (root->leftThread == 0) {
          root->left = insert(root->left, data);
      } else {
          struct Node* temp = createNode(data);
          temp->left = root->left;
          temp->right = root;
          root->leftThread = 1;
          root->left = temp;
      }
  } else {
      // Insert in right subtree
      if (root->rightThread == 0) {
          root->right = insert(root->right, data);
      } else {
          struct Node* temp = createNode(data);
          temp->right = root->right;
          root->rightThread = 1;
            root->right = temp;
        }
    }
    return root;
}
// Inorder traversal of Left Threaded Binary Tree
void inorder(struct Node* root) {
    struct Node* current = root;
    while (current != NULL) {
        // Move to leftmost node
        while (current->leftThread == 0) {
            current = current->left;
        }
        // Print node data
        printf("%d ", current->data);
        // Move to right node (or successor)
        while (current->rightThread == 1) {
            current = current->right;
            printf("%d ", current->data);
        }
        current = current->right;
    }
}
int main() {
    struct Node* root = NULL;
    int choice, data;
    while (1) {
    printf("\n1. Insert a node into the tree\n2. Display Inorder
Traversal\n3. Exit\nEnter your choice: ");
        scanf("%d", &choice);
        switch (choice) {
          case 1:
            printf("Enter the value to insert: ");
            scanf("%d", &data);
            root = insert(root, data);
            break;
          case 2:
         printf("Inorder traversal of the Left Threaded Binary
Tree:\n");
            inorder(root);
            printf("\n");
              break;
            case 3:
              exit(0);
            default:
              printf("Invalid choice, please try again.\n");
        }
    }
    return 0;
}