Data Structure using C
Interview Questions with Answers

1. How do you insert and delete an element in an array in C?

Answer:

Insert at Position:

void insert(int arr[], int *n, int pos, int value) {
   for (int i = *n; i > pos; i--) {
       arr[i] = arr[i - 1];
   }
   arr[pos] = value;
   (*n)++;
} 

Delete at Position

void delete(int arr[], int *n, int pos) {
    for (int i = pos; i < *n - 1; i++) {
       arr[i] = arr[i + 1];
   }
   (*n)--;
}

Use a size variable to track valid array size.

Crack the Code – Master Core Concepts of Data Structures in C!

2. What is an array? How is it stored in memory in C?

Answer:

An array in C is a collection of homogeneous data elements stored in contiguous memory locations, accessed using indices. 

Syntax

int arr[5] = {10, 20, 30, 40, 50};

  • Indexing starts from 0.
  • Stored in contiguous memory, meaning each element follows the previous one in RAM.

Memory Representation: If arr[5] is declared and base address = 1000, and each int is 4 bytes:

ElementValueAddress
arr[0]101000
arr[1]201004
arr[2]301008
arr[3]401012
arr[4]501016

 

3. Write a C program to reverse an array.

Answer:

#include <stdio.h>
void reverse(int arr[], int n) {
    int temp;
    for (int i = 0; i < n / 2; i++) {
        temp = arr[i];
        arr[i] = arr[n - i - 1];
        arr[n - i - 1] = temp;
    }
}
int main() {
int arr[] = {1, 2, 3, 4, 5}, n = 5;
reverse(arr, n);
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}

4. How to find the duplicate elements in an array using C?

Answer:

#include <stdio.h>
void findDuplicates(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (arr[i] == arr[j]) {
                printf("Duplicate found: %d\n", arr[i]);
                break;
            }
        }
    }
}
int main() {
int arr[] = {1, 2, 3, 2, 4, 5, 1};
int n = 7;
findDuplicates(arr, n);
return 0;
}

5. What is a 2D array? How is it represented in memory?

Answer:

A 2D array is an array of arrays, typically used for representing matrices.

Syntax

int matrix[3][3]; 

Memory Representation:

  • Stored in row-major order.
  • If matrix[2][2] = {{1,2},{3,4}}:
    • Memory layout: 1, 2, 3, 4 (sequential)
To access matrix[i][j]:
Address = base_address + ((i * columns) + j) * size_of_element

6. Write a C program to perform matrix multiplication.

Answer:

#include <stdio.h>
int main() {
    int A[2][2] = {{1, 2}, {3, 4}};
    int B[2][2] = {{5, 6}, {7, 8}};
    int C[2][2] = {0};
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
    printf("Result:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            printf("%d ", C[i][j]);
        }
        printf("\n");
    }
    return 0;
}

7. How do you implement dynamic arrays using malloc() in C?

Answer:

#include <stdio.h>
#include <stdlib.h>
int main() {
    int *arr;
    int n;
    printf("Enter size: ");
    scanf("%d", &n);
    arr = (int*) malloc(n * sizeof(int));  // Allocate
    if (arr == NULL) {
        printf("Memory allocation failed");
        return 1;
    }
    for (int i = 0; i < n; i++)
        arr[i] = i + 1;
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    free(arr);  // Deallocate
return 0;
}

8. How is string manipulation done in C without string.h functions?

Answer:

You can manipulate strings using loops and character arrays manually. 

Example – strlen()

int my_strlen(char str[]) {
    int i = 0;
    while (str[i] != '\0')
        i++;
    return i;
} 

Example – strcpy()

void my_strcpy(char dest[], char src[]) {
    int i = 0;
    while ((dest[i] = src[i]) != '\0')
        i++;
}

9. Write a C program to check if a string is a palindrome.

Answer:

#include <stdio.h>
int isPalindrome(char str[]) {
    int start = 0, end = 0;
    while (str[end] != '\0') end--;
    end--;
    while (start < end) {
        if (str[start] != str[end])
            return 0;
        start++;
        end--;
    }
    return 1;
}
int main() {
char str[100];
printf("Enter a string: ");
scanf("%s", str);
if (isPalindrome(str))
printf("Palindrome\n");
else
printf("Not Palindrome\n");
return 0;
}

10. What is the difference between character arrays and strings in C?

Answer:

FeatureCharacter ArrayString (Null-terminated char array)
DefinitionSequence of charactersChar array ending with ‘\0’
TerminationMay or may not end with ‘\0’Must end with ‘\0’
UseAny character bufferRepresents readable textual data
FunctionsUsed manuallyHandled via <string.h> (e.g., strlen)

 Example

char arr[5] = {'H', 'e', 'l', 'l', 'o'};               // Not a string
char str[] = "Hello";                                  // Valid string (with '\0')

11. What is a linked list? How is it different from an array?

Answer:

A linked list is a linear data structure where each element (called a node) contains:

  • Data
  • A pointer to the next node

Differences Between Array and Linked List:

FeatureArrayLinked List
Memory AllocationContiguous (static/dynamic)Non-contiguous (dynamic only)
SizeFixed (unless reallocated)Dynamic (grows/shrinks at runtime)
Insertion/DeletionCostly (due to shifting)Easy (just update pointers)
Random AccessAllowed (O(1))Not allowed (O(n))

 

12. How do you create a singly linked list in C?

Answer:

A singly linked list has nodes with data and a pointer to the next node.

#include <stdio.h>
#include <stdlib.h>
struct Node {
    int data;
    struct Node* next;
};
int main() {
    struct Node *head = NULL, *second = NULL, *third = NULL;
head = (struct Node*) malloc(sizeof(struct Node));
second = (struct Node*) malloc(sizeof(struct Node));
third = (struct Node*) malloc(sizeof(struct Node));
head->data = 10; head->next = second;
second->data = 20; second->next = third;
third->data = 30; third->next = NULL;
return 0;
}

13. Write a C program to insert a node at the beginning of a linked list.

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void insertAtBeginning(struct Node** head_ref, int val) {
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = val;
newNode->next = *head_ref;
*head_ref = newNode;
}
void display(struct Node* head) {
while (head) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}
int main() {
struct Node* head = NULL;
insertAtBeginning(&head, 30);
insertAtBeginning(&head, 20);
insertAtBeginning(&head, 10);
display(head);
return 0;
}

14. Write a C program to delete a node from a linked list by value.

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void deleteByValue(struct Node** head_ref, int val) {
struct Node* temp = *head_ref, *prev = NULL;
if (temp && temp->data == val) {
*head_ref = temp->next;
free(temp);
return;
}
while (temp && temp->data != val) {
prev = temp;
temp = temp->next;
}
if (!temp) return;
prev->next = temp->next;
free(temp);
}
void display(struct Node* head) {
while (head) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}
int main() {
struct Node* head = NULL;
head = (struct Node*) malloc(sizeof(struct Node));
head->data = 10;
head->next = (struct Node*) malloc(sizeof(struct Node));
head->next->data = 20;
head->next->next = NULL;
deleteByValue(&head, 10);
display(head);
return 0;
}

15. What are the advantages of using linked lists over arrays?

Answer:

  • Dynamic size: No need to declare fixed size in advance.
  • Efficient insertions/deletions: Especially in middle or beginning (O(1)).
  • No memory waste: Allocated as needed.
  • No need to shift elements like in arrays.
  • Flexibility: Can easily implement stacks, queues, hash tables, etc.

16. How do you reverse a singly linked list in C?

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void reverseList(struct Node** head_ref) {
struct Node *prev = NULL, *curr = *head_ref, *next = NULL;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
*head_ref = prev;
}
void display(struct Node* head) {
while (head) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}
int main() {
struct Node* head = NULL;
head = (struct Node*) malloc(sizeof(struct Node));
head->data = 1;
head->next = (struct Node*) malloc(sizeof(struct Node));
head->next->data = 2;
head->next->next = NULL;
reverseList(&head);
display(head);
return 0;
}

17.What is a circular linked list and how is it implemented?

Answer:

A circular linked list is a variation where the last node points to the head, forming a circle. 

Implementation

struct Node {
    int data;
    struct Node* next;
};
int main() {
    struct Node *head = (struct Node*) malloc(sizeof(struct Node));
    struct Node *second = (struct Node*) malloc(sizeof(struct Node));
    head->data = 1;
    head->next = second;
    second->data = 2;
    second->next = head;  // Circular link
    return 0;
}

Used in applications like buffer management, round-robin schedulers, etc.

18. What is a doubly linked list and how is it better than singly linked list?

Answer:

A doubly linked list is a type of linked list where each node contains:

  • A data field
  • A pointer to the next node
  • A pointer to the previous node

Benefits over Singly Linked List:

  • Bidirectional traversal
  • Easier deletion (especially from end or middle)
  • More flexible navigation

Structure

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

19. Write a C program to find the middle of a linked list.

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
int findMiddle(struct Node* head) {
struct Node *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow->data;
}
int main() {
struct Node* head = NULL;
head = (struct Node*) malloc(sizeof(struct Node));
head->data = 1;
head->next = (struct Node*) malloc(sizeof(struct Node));
head->next->data = 2;
head->next->next = (struct Node*) malloc(sizeof(struct Node));
head->next->next->data = 3;
head->next->next->next = NULL;
printf("Middle Element: %d\n", findMiddle(head));
return 0;
}

20. How can you detect a cycle in a linked list?

Answer:

Use Floyd’s Cycle Detection Algorithm (Tortoise and Hare method):

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
int hasCycle(struct Node* head) {
struct Node *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
return 1;
}
return 0;
}
int main() {
struct Node* head = (struct Node*) malloc(sizeof(struct Node));
head->data = 1;
head->next = (struct Node*) malloc(sizeof(struct Node));
head->next->data = 2;
head->next->next = head;  // Creating a cycle
if (hasCycle(head))
printf("Cycle Detected\n");
else
printf("No Cycle\n");
return 0;
}

Be Interview-Ready – Sharpen Your Skills with Real Q&A!

21. What is a stack? How is it implemented in C using arrays?

Answer:

A stack is a linear data structure that follows the Last In First Out (LIFO) principle.

 Operations:

  • push() – Insert at the top
  • pop() – Remove from the top
  • peek() – View top element 

Array Implementation

#include <stdio.h>
#define SIZE 100
int stack[SIZE], top = -1;
void push(int val) {
    if (top == SIZE - 1) {
        printf("Stack Overflow\n");
        return;
    }
    stack[++top] = val;
}
int pop() {
    if (top == -1) {
        printf("Stack Underflow\n");
        return -1;
    }
    return stack[top--];
}

22. What is the difference between stack and heap memory?

Answer:

FeatureStack MemoryHeap Memory
AllocationAutomatically by compilerManually by programmer (malloc)
Access SpeedFasterSlower
Size LimitLimitedLarge (depends on RAM)
LifespanEnds when function exitsUntil free() is called
UsageLocal variables, function callsDynamic data structures (linked list, etc.)

 

23. Write a C program to implement stack using linked list.

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
struct Node* top = NULL;
void push(int val) {
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = val;
newNode->next = top;
top = newNode;
}
int pop() {
if (top == NULL) {
printf("Stack Underflow\n");
return -1;
}
int val = top->data;
struct Node* temp = top;
top = top->next;
free(temp);
return val;
}
void display() {
struct Node* temp = top;
while (temp) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
int main() {
push(10); push(20); push(30);
display();         // 30 -> 20 -> 10 -> NULL
pop(); display();  // 20 -> 10 -> NULL
return 0;
}

24. What is stack overflow and how can you prevent it?

Answer:

A stack overflow occurs when the stack exceeds its size limit, either:

  • In array-based stack: inserting more than its capacity
  • In recursion: too many function calls without returning 

Prevention:

  • In arrays: Check top == SIZE – 1 before push()
  • In recursion: Ensure base case exists and avoid infinite recursion
  • Use dynamic stack (linked list) when size is unknown

25. Write a program to convert infix expression to postfix using stack.

Answer:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define SIZE 100 char stack[SIZE]; int top = -1; int precedence(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; return 0; } void push(char c) { stack[++top] = c; } char pop() { return stack[top--]; } char peek() { return stack[top]; } void infixToPostfix(char* expr) { for (int i = 0; expr[i]; i++) { char ch = expr[i]; if (isalnum(ch)) printf("%c", ch); else if (ch == '(') push(ch); else if (ch == ')') { while (peek() != '(') printf("%c", pop()); pop(); // remove '(' } else { while (top != -1 && precedence(ch) <= precedence(peek())) printf("%c", pop()); push(ch); } } while (top != -1) printf("%c", pop()); } int main() { char expr[] = "a+b*(c-d)"; printf("Postfix: "); infixToPostfix(expr);  // Output: abcd-*+ return 0; }

26. How to evaluate postfix expression using a stack in C?

Answer:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE 100 int stack[SIZE], top = -1; void push(int val) { stack[++top] = val; } int pop() { return stack[top--]; } int evaluate(char* exp) { for (int i = 0; exp[i]; i++) { char ch = exp[i]; if (isdigit(ch)) push(ch - '0'); else { int b = pop(), a = pop(); switch (ch) { case '+': push(a + b); break; case '-': push(a - b); break; case '*': push(a * b); break; case '/': push(a / b); break; } } } return pop(); } int main() { char exp[] = "53*2+"; printf("Result: %d\n", evaluate(exp));  // Output: 17 return 0; }

27. Explain real-life applications of stack data structure.

Answer:

  • Undo/Redo functionality (text editors)
  • Function call management (call stack)
  • Balanced parentheses checker
  • Expression evaluation (infix → postfix)
  • Backtracking algorithms (maze solving, recursion)
  • Browser history navigation

28. What are the basic operations of a stack (push, pop, peek) in C?

Answer:

#define SIZE 100
int stack[SIZE], top = -1;
void push(int val) { if (top == SIZE - 1) { printf("Stack Overflow\n"); return; } stack[++top] = val; } int pop() { if (top == -1) { printf("Stack Underflow\n"); return -1; } return stack[top--]; } int peek() { if (top == -1) return -1; return stack[top]; }

29. How can you reverse a string using stack in C?

Answer:

#include <stdio.h>
#include <string.h>
#define SIZE 100 char stack[SIZE]; int top = -1; void push(char c) { stack[++top] = c; } char pop() { return stack[top--]; } int main() { char str[] = "Hello"; int len = strlen(str); for (int i = 0; i < len; i++) push(str[i]); for (int i = 0; i < len; i++) str[i] = pop(); printf("Reversed: %s\n", str);  // Output: olleH return 0; }

30. How do you check for balanced parentheses using stack in C?

Answer:

#include <stdio.h>
#define SIZE 100
char stack[SIZE]; int top = -1; void push(char c) { stack[++top] = c; } char pop() { if (top == -1) return '\0'; return stack[top--]; } int isBalanced(char* exp) { for (int i = 0; exp[i]; i++) { if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[') push(exp[i]); else if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']') { char open = pop(); if ((exp[i] == ')' && open != '(') || (exp[i] == '}' && open != '{') || (exp[i] == ']' && open != '[')) return 0; } } return top == -1; } int main() { char exp[] = "{(a+b)*[c-d]}"; if (isBalanced(exp)) printf("Balanced\n"); else printf("Not Balanced\n"); return 0; }

31. What is a queue? How is it implemented in C using arrays?

Answer:

A queue is a linear data structure that follows the FIFO (First In First Out) principle. 

Basic Operations:

  • enqueue() – Add element at the rear
  • dequeue() – Remove element from the front

Array Implementation

#include <stdio.h>
#define SIZE 5
int queue[SIZE]; int front = -1, rear = -1; void enqueue(int val) { if (rear == SIZE - 1) { printf("Queue Overflow\n"); return; } if (front == -1) front = 0; queue[++rear] = val; } int dequeue() { if (front == -1 || front > rear) { printf("Queue Underflow\n"); return -1; } return queue[front++]; }

32. Write a C program to implement circular queue.

Answer:

#include <stdio.h>
#define SIZE 5
int queue[SIZE]; int front = -1, rear = -1; int isFull() { return (rear + 1) % SIZE == front; } int isEmpty() { return front == -1; } void enqueue(int val) { if (isFull()) { printf("Queue Overflow\n"); return; } if (isEmpty()) front = rear = 0; else rear = (rear + 1) % SIZE; queue[rear] = val; } int dequeue() { if (isEmpty()) { printf("Queue Underflow\n"); return -1; } int val = queue[front]; if (front == rear) front = rear = -1; else front = (front + 1) % SIZE; return val; } void display() { if (isEmpty()) { printf("Queue is Empty\n"); return; } printf("Queue: "); int i = front; do { printf("%d ", queue[i]); i = (i + 1) % SIZE; } while (i != (rear + 1) % SIZE); printf("\n"); } int main() { enqueue(10); enqueue(20); enqueue(30); enqueue(40); dequeue(); dequeue(); enqueue(50); enqueue(60); display();  // Expected: 30 40 50 60 return 0; }

33. How is a queue implemented using linked list?

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node { int data; struct Node* next; }; struct Node *front = NULL, *rear = NULL; void enqueue(int val) { struct Node* newNode = (struct Node*) malloc(sizeof(struct Node)); newNode->data = val; newNode->next = NULL; if (rear == NULL) front = rear = newNode; else { rear->next = newNode; rear = newNode; } } int dequeue() { if (front == NULL) { printf("Queue Underflow\n"); return -1; } int val = front->data; struct Node* temp = front; front = front->next; if (front == NULL) rear = NULL; free(temp); return val; } void display() { struct Node* temp = front; while (temp) { printf("%d -> ", temp->data); temp = temp->next; } printf("NULL\n"); }

34. What is the difference between queue and stack?

Answer:

FeatureStack (LIFO)Queue (FIFO)
AccessLast inserted is accessed firstFirst inserted is accessed first
Operationspush, pop, peekenqueue, dequeue, front, rear
Use CasesRecursion, Undo, Expression evalScheduling, Buffers, OS task queue

 

35. What is a dequeue (double-ended queue)?

Answer:

A deque (double-ended queue) is a linear data structure in which insertion and deletion can be done from both front and rear ends. 

Types of Deques:

  • Input-restricted: Insertion only at rear
  • Output-restricted: Deletion only from front 

Use Cases:

  • Task scheduling
  • Palindrome checking
  • Sliding window problems in algorithms

36. Write a C program for priority queue implementation.

Answer:

#include <stdio.h>
#define SIZE 10
struct PQ { int data; int priority; } pq[SIZE]; int count = 0; void insert(int data, int priority) { if (count == SIZE) { printf("Priority Queue Overflow\n"); return; } int i = count - 1; while (i >= 0 && pq[i].priority > priority) { pq[i + 1] = pq[i]; i--; } pq[i + 1].data = data; pq[i + 1].priority = priority; count++; } int delete() { if (count == 0) { printf("Priority Queue Underflow\n"); return -1; } return pq[--count].data; } void display() { for (int i = 0; i < count; i++) printf("(%d, P%d) ", pq[i].data, pq[i].priority); printf("\n"); } int main() { insert(30, 2); insert(10, 1); insert(20, 3); display();      // Output: (10, P1) (30, P2) (20, P3) delete(); display(); return 0; }

37. What is queue overflow and underflow?

Answer:

  • Queue Overflow: Occurs when trying to enqueue an element in a full queue.
  • Queue Underflow: Occurs when trying to dequeue from an empty queue.

Prevention:

  • Check rear == SIZE – 1 for array-based queue.
  • Use circular queues to optimize space.

38. How do you simulate a real-world task scheduler using queue in C?

Answer:

Use a queue to simulate task scheduling, where tasks are added and executed in order. 

Example

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Task { char name[20]; struct Task* next; }; struct Task *front = NULL, *rear = NULL; void addTask(char name[]) { struct Task* newTask = (struct Task*) malloc(sizeof(struct Task)); strcpy(newTask->name, name); newTask->next = NULL; if (rear == NULL) front = rear = newTask; else { rear->next = newTask; rear = newTask; } } void runTask() { if (front == NULL) { printf("No tasks to run\n"); return; } printf("Running task: %s\n", front->name); struct Task* temp = front; front = front->next; free(temp); if (front == NULL) rear = NULL; } int main() { addTask("Compile Code"); addTask("Run Tests"); addTask("Deploy App"); runTask(); runTask(); runTask(); return 0; }

39. What is the difference between linear queue and circular queue?

Answer:

FeatureLinear QueueCircular Queue
Memory EfficiencyInefficient (unused front space)Efficient (reuses space using modulo)
Rear InsertionStops at SIZE – 1Wraps around using (rear + 1) % SIZE
Use CaseSimple tasksFixed-size scheduling, ring buffers

 

40. What are some real-life applications of queues?

Answer:

  • CPU and task scheduling
  • Printer spooling
  • Network routers and packets
  • Customer service systems
  • Breadth-first search (BFS)
  • Order processing systems
  • Operating system I/O management

Turn Your Knowledge into Offers – Start Practicing Today!

41. What is a binary tree?

Answer:

A binary tree is a hierarchical tree data structure in which each node has at most two children, commonly referred to as:

  • Left child
  • Right child

Properties:

  • The topmost node is called the root.
  • Nodes with no children are called leaves.
  • Each subtree is also a binary tree.

42. How do you implement binary tree in C?

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};
struct Node* createNode(int val) {
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = val;
newNode->left = newNode->right = NULL;
return newNode;
}
  • left and right pointers point to the child nodes.
  • createNode() dynamically creates a node.

43. Write a C program for in-order, pre-order and post-order traversal.

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* left;
struct Node* right;
};
struct Node* createNode(int val) {
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = val;
node->left = node->right = NULL;
return node;
}
void inorder(struct Node* root) {
if (root) {
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}
void preorder(struct Node* root) {
if (root) {
printf("%d ", root->data);
preorder(root->left);
preorder(root->right);
}
}
void postorder(struct Node* root) {
if (root) {
postorder(root->left);
postorder(root->right);
printf("%d ", root->data);
}
}
int main() {
struct Node* root = createNode(10);
root->left = createNode(5);
root->right = createNode(20);
printf("Inorder: "); inorder(root); printf("\n");
printf("Preorder: "); preorder(root); printf("\n");
printf("Postorder: "); postorder(root); printf("\n");
return 0;
}

44. What is the difference between binary tree and binary search tree?

Answer:

FeatureBinary TreeBinary Search Tree (BST)
Node StructureEach node has ≤ 2 childrenSame
OrderingNo ordering of elementsLeft < Root < Right
SearchingO(n) in generalO(log n) if balanced
Use CaseGeneral purposeEfficient searching, insertion, deletion

 

45. Write a program to insert a node in a binary search tree.

Answer:

#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* left;
struct Node* right;
};
struct Node* createNode(int val) {
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = val;
node->left = node->right = NULL;
return node;
}
struct Node* insert(struct Node* root, int val) {
if (root == NULL)
return createNode(val);
if (val < root->data)
root->left = insert(root->left, val);
else if (val > root->data)
root->right = insert(root->right, val);
return root;
}
void inorder(struct Node* root) {
if (root) {
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}
int main() {
struct Node* root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 70);
insert(root, 20);
insert(root, 40);
printf("Inorder traversal: ");
inorder(root);
return 0;
}

46. How do you search for a value in a binary search tree in C?

Answer:

int search(struct Node* root, int key) 
{    if (root == NULL) return 0;    if (key == root->data) return 1;    else if (key < root->data) return search(root->left, key);    else return search(root->right, key); }
  • Efficient due to binary structure (O(log n) in balanced BST).
  • Recursive or iterative approaches are valid.

47. What is height and depth of a binary tree?

Answer:

  • Height of a Node: Number of edges on the longest path from the node to a leaf.
  • Height of Tree: Height of the root node.
  • Depth of a Node: Number of edges from the root to the node. 

Example

For the tree:

  1
/ \
2 3
/
4
  • Height of node 2 = 1
  • Depth of node 4 = 2
  • Height of tree = 2

48. Write a program to find the height of a binary tree.

Answer:

int height(struct Node* root) {
    if (root == NULL) return -1; // or return 0 for counting nodes
    int left = height(root->left);
    int right = height(root->right);
    return 1 + (left > right ? left : right);
}
Call using: height(root)

49. What is a balanced binary tree?

Answer:

A balanced binary tree is a tree where for every node, the difference in height between its left and right subtrees is at most 1.

Types:

  • AVL Tree: Strictly balanced with rotation
  • Red-Black Tree: Loosely balanced with color rules

 Benefit: Ensures O(log n) performance for operations.

50. What is the difference between complete, full, and perfect binary tree?

Answer:

Tree TypeDefinition
Full Binary TreeEvery node has 0 or 2 children
Complete Binary TreeAll levels filled except the last, filled from left to right
Perfect Binary TreeAll internal nodes have 2 children and all leaves are at same level

 Example

Perfect Tree:

   1
/   \
2    3
/ \   / \
4  5 6   7

Complete Tree:

   1
/   \
2    3
/ \   /
4  5 6

Full Tree:

   1
/   \
2    3
/ \
4  5

51. What is a hash table and how do you implement it in C?

Answer:

A hash table is a data structure that maps keys to values using a hash function.

  • Keys are hashed to indices in an array.
  • Collisions are handled via chaining or open addressing. 

Simple Hash Table using Chaining (Linked List):

#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
struct Node {
    int key;
    struct Node* next;
};
struct Node* table[SIZE];
int hash(int key) {
    return key % SIZE;
}
void insert(int key) {
    int idx = hash(key);
    struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
    newNode->key = key;
    newNode->next = table[idx];
    table[idx] = newNode;
}
void display() {
    for (int i = 0; i < SIZE; i++) {
        printf("[%d]: ", i);
        struct Node* temp = table[i];
        while (temp) {
            printf("%d -> ", temp->key);
            temp = temp->next;
        }
        printf("NULL\n");
    }
}

52. What are collision handling techniques in hashing?

Answer:

A collision occurs when two keys hash to the same index.

 Collision Resolution Techniques:

  1. Chaining:
    • Store multiple elements in a linked list at the same index.
    • Simple and easy to implement.
  2. Open Addressing:
    • Probe next available slots.
    • Types:
      • Linear Probing: idx = (h + i) % size
      • Quadratic Probing: idx = (h + i²) % size
      • Double Hashing: Use second hash function for offset.

53. What is a graph and how is it represented in C?

Answer:

A graph is a collection of nodes (vertices) and edges. 

Graph Representations in C:

  1. Adjacency Matrix:

int graph[5][5]; // 0 = no edge, 1 = edge

  1. Adjacency List:
struct Node {
    int vertex;
    struct Node* next;
};
struct Node* adjList[V];
  • Adjacency list is space-efficient for sparse graphs.
  • Adjacency matrix is good for dense graphs.

54. Write a C program for BFS (Breadth First Search) in a graph.

Answer:

#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
int adj[SIZE][SIZE], visited[SIZE];
int queue[SIZE], front = 0, rear = 0;
void enqueue(int val) { queue[rear++] = val; }
int dequeue() { return queue[front++]; }
void bfs(int start, int vertices) {
visited[start] = 1;
enqueue(start);
while (front < rear) {
int curr = dequeue();
printf("%d ", curr);
for (int i = 0; i < vertices; i++) {
if (adj[curr][i] && !visited[i]) {
enqueue(i);
visited[i] = 1;
}
}
}
}
int main() {
int vertices = 5;
adj[0][1] = adj[1][0] = 1;
adj[0][2] = adj[2][0] = 1;
adj[1][3] = adj[3][1] = 1;
adj[2][4] = adj[4][2] = 1;
printf("BFS starting from vertex 0: ");
bfs(0, vertices);
return 0;
}

55. Write a C program for DFS (Depth First Search) in a graph.

Answer:

#include <stdio.h>
#define SIZE 100
int adj[SIZE][SIZE], visited[SIZE];
void dfs(int v, int vertices) {
    printf("%d ", v);
    visited[v] = 1;
    for (int i = 0; i < vertices; i++) {
        if (adj[v][i] && !visited[i]) {
            dfs(i, vertices);
        }
    }
}
int main() {
int vertices = 5;
adj[0][1] = adj[1][0] = 1;
adj[0][2] = adj[2][0] = 1;
adj[1][3] = adj[3][1] = 1;
adj[2][4] = adj[4][2] = 1;
printf("DFS starting from vertex 0: ");
dfs(0, vertices);
return 0;
}

56. What is a heap? How is it implemented in C?

Answer:

A heap is a complete binary tree that satisfies the heap property:

  • Max Heap: Parent ≥ Children
  • Min Heap: Parent ≤ Children

Array Implementation (Min Heap):

#define SIZE 100
int heap[SIZE], count = 0;
void insert(int val) {
int i = count++;
heap[i] = val;
while (i != 0 && heap[(i - 1) / 2] > heap[i]) {
int temp = heap[i];
heap[i] = heap[(i - 1) / 2];
heap[(i - 1) / 2] = temp;
i = (i - 1) / 2;
}
}

57. Explain quick sort and write its C implementation.

Answer:

Quick Sort is a divide-and-conquer sorting algorithm:

  • Select a pivot.
  • Partition the array around pivot.
  • Recursively sort left and right parts.

 Example

int partition(int arr[], int low, int high) {
    int pivot = arr[high], i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] <= pivot) {
            i++;
            int t = arr[i]; arr[i] = arr[j]; arr[j] = t;
        }
    }
    int t = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = t;
    return i + 1;
}
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int p = partition(arr, low, high);
        quickSort(arr, low, p - 1);
        quickSort(arr, p + 1, high);
    }
}

58. Explain merge sort and write its C implementation.

Answer:

Merge Sort is a stable, divide-and-conquer algorithm:

  • Divide the array into halves.
  • Recursively sort both halves.
  • Merge them back.

 Example

void merge(int arr[], int l, int m, int r) {
    int n1 = m - l + 1, n2 = r - m;
    int L[n1], R[n2];
    for (int i = 0; i < n1; i++) L[i] = arr[l + i];
    for (int j = 0; j < n2; j++) R[j] = arr[m + 1 + j];
    int i = 0, j = 0, k = l;
    while (i < n1 && j < n2) {
        arr[k++] = (L[i] <= R[j]) ? L[i++] : R[j++];
    }
    while (i < n1) arr[k++] = L[i++];
    while (j < n2) arr[k++] = R[j++];
}
void mergeSort(int arr[], int l, int r) {
    if (l < r) {
        int m = l + (r - l) / 2;
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);
        merge(arr, l, m, r);
    }
}

59.What is the time complexity of binary search and write its code.

Answer:

  • Time Complexity: O(log n)
  • Works only on sorted arrays

 Binary Search Code

int binarySearch(int arr[], int n, int key) {
    int low = 0, high = n - 1;
    while (low <= high) {
        int mid = (low + high) / 2;
        if (arr[mid] == key) return mid;
        else if (arr[mid] < key) low = mid + 1;
        else high = mid - 1;
    }
    return -1; // Not found
}

60. Compare different sorting algorithms.

Answer:

AlgorithmTime Complexity (Best / Avg / Worst)SpaceStableNotes
Bubble SortO(n) / O(n²) / O(n²)O(1)YesSimple but inefficient
Insertion SortO(n) / O(n²) / O(n²)O(1)YesGood for small or nearly sorted
Selection SortO(n²) / O(n²) / O(n²)O(1)NoAlways performs n² comparisons
Merge SortO(n log n) / O(n log n) / O(n log n)O(n)YesRecursive, good for linked lists
Quick SortO(n log n) / O(n log n) / O(n²)O(log n)NoFastest in practice; in-place sort
Note: The interview questions and answers provided on this page have been thoughtfully compiled by our academic team. However, as the content is manually created, there may be occasional errors or omissions. If you have any questions or identify any inaccuracies, please contact us at team@learn2earnlabs.com. We appreciate your feedback and strive for continuous improvement.