Data Structure using C
Interview Questions with Answers

Explore Our Courses
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:
Element | Value | Address |
arr[0] | 10 | 1000 |
arr[1] | 20 | 1004 |
arr[2] | 30 | 1008 |
arr[3] | 40 | 1012 |
arr[4] | 50 | 1016 |
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:
Feature | Character Array | String (Null-terminated char array) |
Definition | Sequence of characters | Char array ending with ‘\0’ |
Termination | May or may not end with ‘\0’ | Must end with ‘\0’ |
Use | Any character buffer | Represents readable textual data |
Functions | Used manually | Handled 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:
Feature | Array | Linked List |
Memory Allocation | Contiguous (static/dynamic) | Non-contiguous (dynamic only) |
Size | Fixed (unless reallocated) | Dynamic (grows/shrinks at runtime) |
Insertion/Deletion | Costly (due to shifting) | Easy (just update pointers) |
Random Access | Allowed (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:
Feature | Stack Memory | Heap Memory |
Allocation | Automatically by compiler | Manually by programmer (malloc) |
Access Speed | Faster | Slower |
Size Limit | Limited | Large (depends on RAM) |
Lifespan | Ends when function exits | Until free() is called |
Usage | Local variables, function calls | Dynamic 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:
Feature | Stack (LIFO) | Queue (FIFO) |
Access | Last inserted is accessed first | First inserted is accessed first |
Operations | push, pop, peek | enqueue, dequeue, front, rear |
Use Cases | Recursion, Undo, Expression eval | Scheduling, 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:
Feature | Linear Queue | Circular Queue |
Memory Efficiency | Inefficient (unused front space) | Efficient (reuses space using modulo) |
Rear Insertion | Stops at SIZE – 1 | Wraps around using (rear + 1) % SIZE |
Use Case | Simple tasks | Fixed-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:
Feature | Binary Tree | Binary Search Tree (BST) |
Node Structure | Each node has ≤ 2 children | Same |
Ordering | No ordering of elements | Left < Root < Right |
Searching | O(n) in general | O(log n) if balanced |
Use Case | General purpose | Efficient 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 Type | Definition |
Full Binary Tree | Every node has 0 or 2 children |
Complete Binary Tree | All levels filled except the last, filled from left to right |
Perfect Binary Tree | All 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:
- Chaining:
- Store multiple elements in a linked list at the same index.
- Simple and easy to implement.
- 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:
- Adjacency Matrix:
int graph[5][5]; // 0 = no edge, 1 = edge
- 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:
Algorithm | Time Complexity (Best / Avg / Worst) | Space | Stable | Notes |
Bubble Sort | O(n) / O(n²) / O(n²) | O(1) | Yes | Simple but inefficient |
Insertion Sort | O(n) / O(n²) / O(n²) | O(1) | Yes | Good for small or nearly sorted |
Selection Sort | O(n²) / O(n²) / O(n²) | O(1) | No | Always performs n² comparisons |
Merge Sort | O(n log n) / O(n log n) / O(n log n) | O(n) | Yes | Recursive, good for linked lists |
Quick Sort | O(n log n) / O(n log n) / O(n²) | O(log n) | No | Fastest in practice; in-place sort |