Correct Answer: To organize data efficiently
Explanation: Data structures in programming are used to efficiently organize and manage data, facilitating operations like insertion, deletion, and searching.
Correct Answer: Stack
Explanation: A stack data structure follows the Last-In-First-Out (LIFO) principle where the last element added is the first one to be removed.
Correct Answer: Linked List
Explanation: A linked list allows elements to be accessed in both forward and backward directions, but its access time is generally slower compared to arrays due to pointer traversal.
Correct Answer: Constant time complexity for all operations
Explanation: Hash tables provide constant time complexity (O(1)) for insert, delete, and search operations under favorable conditions, making them efficient for many applications.
Correct Answer: Tree
Explanation: A tree data structure is used to represent hierarchical relationships between elements, with a root node at the top and child nodes branching out.
Correct Answer: A data structure with first-in-first-out (FIFO) access
Explanation: A queue data structure follows the FIFO principle where the element added first is the one removed first.
Correct Answer: Stack
Explanation: A stack data structure is ideal for implementing recursion due to its Last-In-First-Out (LIFO) nature, which matches the recursive function call mechanism.
Correct Answer: Each element pointing to the previous and next elements
Explanation: In a doubly linked list, each element contains pointers to both the previous and next elements, enabling bidirectional traversal.
Correct Answer: Binary Heap
Explanation: A binary heap is a specialized tree-based data structure that allows efficient insertion and extraction of the highest (or lowest) priority element.
Correct Answer: Elements having arbitrary relationships between them
Explanation: A graph data structure consists of nodes (vertices) and edges that represent arbitrary relationships between pairs of nodes.
Correct Answer: Each element pointing to the next element only
Explanation: In a singly linked list, each element (node) contains a data field and a pointer to the next node in the sequence.
Correct Answer: Both the next and previous nodes
Explanation: Doubly linked lists have nodes that contain pointers to both the next and previous nodes, allowing bidirectional traversal.
Correct Answer: Its last node points back to the head node
Explanation: A circular linked list connects the last node back to the head node, forming a circular loop.
Correct Answer: Insertion at the beginning
Explanation: Insertion at the beginning of a singly linked list is more efficient (O(1)) compared to a doubly linked list (O(1)) due to the lack of a previous pointer.
Correct Answer: O(n)
Explanation: Inserting a node at the end of a singly linked list requires traversing the entire list to reach the last node, resulting in O(n) time complexity.
Correct Answer: Doubly linked list
Explanation: Doubly linked lists allow traversal from both the head to tail and from tail to head with equal efficiency.
Correct Answer: Support for dynamic memory allocation
Explanation: Circular linked lists support dynamic memory allocation and are useful in applications where continuous access to elements is needed.
Correct Answer: Doubly linked list
Explanation: Doubly linked lists allow efficient insertions and deletions at both the head and tail ends due to bidirectional traversal capability.
Correct Answer: Deletion of the head node
Explanation: Deleting the head node in a circular linked list requires special handling to adjust pointers and maintain the circular structure.
Correct Answer: Doubly linked list
Explanation: Doubly linked lists are ideal for implementing an LRU cache as they allow constant time complexity for insertion, deletion, and moving nodes to the front based on recent usage.
struct Node {
int data;
struct Node *next;
};
What type of linked list does this structure represent?
Correct Answer: Singly linked list
Explanation: The given struct definition represents a singly linked list node with a data field and a pointer to the next node.
struct Node *insertAtBeginning(struct Node *head, int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = head;
return newNode;
}
Correct Answer: Insertion at the beginning
Explanation: The function `insertAtBeginning` inserts a new node with the given value at the beginning of a singly linked list.
void deleteNode(struct Node **head_ref, int key) {
struct Node *temp = *head_ref, *prev;
if (temp != NULL && temp->data == key) {
*head_ref = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}
Correct Answer: Deletion of a node by key
Explanation: The function `deleteNode` deletes a node from a singly linked list based on the given key value.
void insertAtEnd(struct Node **head_ref, int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
struct Node *last = *head_ref;
newNode->data = value;
newNode->next = NULL;
if (*head_ref == NULL) {
newNode->prev = NULL;
*head_ref = newNode;
return;
}
while (last->next != NULL)
last = last->next;
last->next = newNode;
newNode->prev = last;
}
Correct Answer: Insertion at the end
Explanation: The function `insertAtEnd` inserts a new node with the given value at the end of a doubly linked list.
struct Node {
int data;
struct Node *next;
};
struct Node *createCircularLinkedList(int arr[], int n) {
if (n == 0) return NULL;
struct Node *head = (struct Node *)malloc(sizeof(struct Node));
head->data = arr[0];
head->next = head;
struct Node *current = head;
for (int i = 1; i < n; ++i) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = arr[i];
newNode->next = head;
current->next = newNode;
current = newNode;
}
return head;
}
What type of linked list does this function create?
Correct Answer: Circular linked list
Explanation: The function `createCircularLinkedList` creates a circular linked list where the last node points back to the head node.
void traverseAndPrint(struct Node *head) {
struct Node *temp = head;
if (head != NULL) {
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("Head");
}
}
Correct Answer: Traversal and printing of a circular linked list
Explanation: The function `traverseAndPrint` traverses and prints the elements of a circular linked list starting from the head node.
void deleteHeadNode(struct Node **head_ref) {
if (*head_ref == NULL) return;
struct Node *temp = *head_ref;
struct Node *current = *head_ref;
while (current->next != *head_ref)
current = current->next;
if (current == *head_ref) {
*head_ref = NULL;
} else {
current->next = temp->next;
*head_ref = temp->next;
}
free(temp);
}
Correct Answer: Deletion of the head node
Explanation: The function `deleteHeadNode` deletes the head node of a circular linked list and adjusts pointers accordingly.
struct Node *reverseLinkedList(struct Node *head) {
struct Node *prev = NULL;
struct Node *current = head;
struct Node *next = NULL;
while (current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
What is the purpose of this function?
Correct Answer: Reversing a singly linked list
Explanation: The function `reverseLinkedList` reverses the given singly linked list by changing the direction of pointers.
void deleteLastNode(struct Node **head_ref) {
if (*head_ref == NULL) return;
struct Node *temp = *head_ref;
while (temp->next != NULL)
temp = temp->next;
if (temp->prev != NULL)
temp->prev->next = NULL;
else
*head_ref = NULL;
free(temp);
}
Correct Answer: Deletion at the end
Explanation: The function `deleteLastNode` deletes the last node of a doubly linked list by adjusting pointers and freeing memory.
int hasCycle(struct Node *head) {
struct Node *slow = head;
struct Node *fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
return 1; // Cycle detected
}
return 0; // No cycle found
}
What does this function determine about the given linked list?
Correct Answer: Whether it contains a cycle
Explanation: The function `hasCycle` determines whether the given singly linked list contains a cycle by using a slow and fast pointer approach.
Correct Answer: Last-In-First-Out (LIFO) access
Explanation: A stack data structure follows the Last-In-First-Out (LIFO) principle, where the last element added is the first one to be removed.
#define MAX_SIZE 100
int stack[MAX_SIZE];
int top = -1;
void push(int value) {
if (top >= MAX_SIZE - 1) {
printf("Stack Overflow\n");
return;
}
stack[++top] = value;
}
Correct Answer: Push operation
Explanation: The function `push` pushes (inserts) an element onto the top of the stack implemented using an array.
int pop() {
if (top < 0) {
printf("Stack Underflow\n");
return -1;
}
return stack[top--];
}
Correct Answer: Pop operation
Explanation: The function `pop` removes and returns the element from the top of the stack implemented using an array.
int isEmpty() {
return (top < 0);
}
What does this function determine about the stack?
Correct Answer: Whether it is empty
Explanation: The function `isEmpty` checks if the stack implemented using an array is empty by evaluating the top index.
int peek() {
if (top < 0) {
printf("Stack is empty\n");
return -1;
}
return stack[top];
}
Correct Answer: Peek operation
Explanation: The function `peek` returns the element from the top of the stack implemented using an array without removing it.
Correct Answer: Array
Explanation: Arrays are commonly used to implement stacks due to their simplicity and efficient access time for push and pop operations.
struct Node {
int data;
struct Node *next;
};
How would you modify this structure to use it as nodes in a linked list to implement a stack?
Correct Answer: No modification needed
Explanation: The given struct definition is already suitable for nodes in a linked list to implement a stack using a singly linked list.
struct Node {
int data;
struct Node *next;
};
struct Node *top = NULL;
void push(int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = top;
top = newNode;
}
Correct Answer: Push operation
Explanation: The function `push` inserts a new node with the given value onto the top of the stack implemented using a linked list.
Correct Answer: O(1)
Explanation: The pop operation in a stack implemented using a singly linked list has a time complexity of O(1) because it only involves adjusting pointers.
int isEmpty() {
return (top == NULL);
}
What does this function determine about the stack?
Correct Answer: Whether it is empty
Explanation: The function `isEmpty` checks if the stack implemented using a linked list is empty by evaluating the `top` pointer.
int peek() {
if (top == NULL) {
printf("Stack is empty\n");
return -1;
}
return top->data;
}
What operation does this function perform?
Correct Answer: Peek operation
Explanation: The function `peek` returns the data value of the top node in a stack implemented using a linked list without removing it.
int pop() {
if (top == NULL) {
printf("Stack Underflow\n");
return -1;
}
struct Node *temp = top;
int data = temp->data;
top = top->next;
free(temp);
return data;
}
Correct Answer: Pop operation
Explanation: The function `pop` removes and returns the top element from a stack implemented using a linked list.
Correct Answer: Deque
Explanation: A deque (double-ended queue) is suitable for implementing a stack that requires efficient insertion and deletion at both ends.
#define MAX_SIZE 100
int stack[MAX_SIZE];
int top = -1;
void push(int value) {
if (top >= MAX_SIZE - 1) {
printf("Stack Overflow\n");
return;
}
stack[++top] = value;
}
int pop() {
if (top < 0) {
printf("Stack Underflow\n");
return -1;
}
return stack[top--];
}
int peek() {
if (top < 0) {
printf("Stack is empty\n");
return -1;
}
return stack[top];
}
int isEmpty() {
return (top < 0);
}
What does this function snippet mainly demonstrate?
Correct Answer: Implementation of a stack using an array
Explanation: The function snippet demonstrates the implementation of a stack data structure using an array in C.
Correct Answer: Push operation
Explanation: Push operation in a stack implemented using an array is more efficient (O(1)) compared to a stack implemented using a linked list (O(1)) due to direct access.
Correct Answer: Limited size
Explanation: Arrays used to implement stacks have a fixed size, leading to potential overflow if the stack size exceeds the predefined maximum size.
Correct Answer: Dynamic size
Explanation: Linked lists used to implement stacks allow dynamic memory allocation, enabling the stack to grow or shrink as needed.
int isFull() {
return (top >= MAX_SIZE - 1);
}
What does this function determine about the stack?
Correct Answer: Whether it is full
Explanation: The function `isFull` checks if the stack implemented using an array has reached its maximum capacity.
#define MAX_SIZE 50
int stack[MAX_SIZE];
int top = -1;
void push(int value) {
if (top >= MAX_SIZE - 1) {
printf("Stack Overflow\n");
return;
}
stack[++top] = value;
}
Correct Answer: Push operation
Explanation: The function `push` inserts an element onto the top of the stack implemented using an array with a fixed size.
int pop() {
if (top < 0) {
printf("Stack Underflow\n");
return -1;
}
return stack[top--];
}
Correct Answer: Pop operation
Explanation: The function `pop` removes and returns the top element from a stack implemented using an array.
Correct Answer: First-In-First-Out (FIFO) access
Explanation: A queue data structure follows the First-In-First-Out (FIFO) principle, where the first element added is the first one to be removed.
#define MAX_SIZE 100
int queue[MAX_SIZE];
int front = -1, rear = -1;
void enqueue(int value) {
if (rear >= MAX_SIZE - 1) {
printf("Queue Overflow\n");
return;
}
if (front == -1)
front = 0;
queue[++rear] = value;
}
Correct Answer: Enqueue operation
Explanation: The function `enqueue` inserts an element into the rear of the queue implemented using an array.
int dequeue() {
if (front == -1 || front > rear) {
printf("Queue Underflow\n");
return -1;
}
return queue[front++];
}
Correct Answer: Dequeue operation
Explanation: The function `dequeue` removes and returns the front element from the queue implemented using an array.
Correct Answer: Deque
Explanation: A deque (double-ended queue) is suitable for implementing a queue that requires efficient insertion and deletion at both ends.
int isEmpty() {
return (front == -1 || front > rear);
}
What does this function determine about the queue?
Correct Answer: Whether it is empty
Explanation: The function `isEmpty` checks if the queue implemented using an array is empty by evaluating the `front` and `rear` indices.
Correct Answer: Enqueue operation
Explanation: Enqueue operation in a queue implemented using an array is more efficient (O(1)) compared to a queue implemented using a linked list (O(1)) due to direct access.
Correct Answer: Limited size
Explanation: Arrays used to implement queues have a fixed size, leading to potential overflow if the queue size exceeds the predefined maximum size.
Correct Answer: Dynamic size
Explanation: Linked lists used to implement queues allow dynamic memory allocation, enabling the queue to grow or shrink as needed.
struct Node {
int data;
struct Node *next;
};
struct Node *front = NULL;
struct Node *rear = NULL;
void enqueue(int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
if (rear == NULL) {
front = newNode;
} else {
rear->next = newNode;
}
rear = newNode;
}
What does this function snippet mainly demonstrate?
Correct Answer: Implementation of a queue using a linked list
Explanation: The function snippet demonstrates the implementation of a queue data structure using a singly linked list in C.
int dequeue() {
if (front == NULL) {
printf("Queue Underflow\n");
return -1;
}
struct Node *temp = front;
int data = temp->data;
front = front->next;
if (front == NULL)
rear = NULL;
free(temp);
return data;
}
Correct Answer: Dequeue operation
Explanation: The function `dequeue` removes and returns the front element from a queue implemented using a linked list.
int peek() {
if (front == NULL) {
printf("Queue is empty\n");
return -1;
}
return front->data;
}
What operation does this function perform?
Correct Answer: Peek operation
Explanation: The function `peek` returns the data value of the front node in a queue implemented using a linked list without removing it.
int isEmpty() {
return (front == NULL);
}
What does this function determine about the queue?
Correct Answer: Whether it is empty
Explanation: The function `isEmpty` checks if the queue implemented using a linked list is empty by evaluating the `front` pointer.
Correct Answer: Deque
Explanation: A deque (double-ended queue) is suitable for implementing a queue that requires efficient insertion at one end (rear) and deletion at the other end (front).
int isFull() {
return 0; // Linked list-based queues do not have a fixed size limit
}
What does this function determine about the queue?
Correct Answer: Whether it is full
Explanation: This function always returns 0 because queues implemented using linked lists do not have a fixed size limit like arrays.
Correct Answer: Enqueue operation
Explanation: Enqueue operation in a queue implemented using a linked list is more efficient (O(1)) compared to a queue implemented using an array (O(1)) due to direct pointer manipulation.
Correct Answer: Inefficient insertion
Explanation: Insertion in a queue implemented using a linked list requires traversal to the rear end, which can be inefficient compared to arrays for large queues.
Correct Answer: Faster access time
Explanation: Access time (enqueue and dequeue operations) in a queue implemented using an array is typically faster than in a linked list due to direct indexing.
#define MAX_SIZE 50
int queue[MAX_SIZE];
int front = -1, rear = -1;
void enqueue(int value) {
if ((rear + 1) % MAX_SIZE == front) {
printf("Queue Overflow\n");
return;
}
if (front == -1)
front = 0;
rear = (rear + 1) % MAX_SIZE;
queue[rear] = value;
}
int dequeue() {
if (front == -1) {
printf("Queue Underflow\n");
return -1;
}
int data = queue[front];
if (front == rear)
front = rear = -1;
else
front = (front + 1) % MAX_SIZE;
return data;
}
What does this function snippet mainly demonstrate?
Correct Answer: Implementation of a circular queue using an array
Explanation: The function snippet demonstrates the implementation of a circular queue data structure using an array in C.
int peek() {
if (front == -1) {
printf("Queue is empty\n");
return -1;
}
return queue[front];
}
Correct Answer: Peek operation
Explanation: The function `peek` returns the data value of the front element in a circular queue implemented using an array without removing it.
int isEmpty() {
return (front == -1);
}
What does this function determine about the circular queue?
Correct Answer: Whether it is empty
Explanation: The function `isEmpty` checks if the circular queue implemented using an array is empty by evaluating the `front` index.
Correct Answer: Two children per node
Explanation: A binary tree is a hierarchical data structure where each node has at most two children.
Correct Answer: Inorder traversal
Explanation: Inorder traversal visits the left subtree, then the root node, and finally the right subtree in a binary tree.
struct Node {
int data;
struct Node *left;
struct Node *right;
};
What does this struct definition represent?
Correct Answer: Definition of a binary tree node
Explanation: This C struct defines a node structure for a binary tree, where each node contains integer data and pointers to left and right child nodes.
struct Node *createNode(int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
Correct Answer: Initialization operation
Explanation: The function `createNode` initializes and returns a new node with the given integer value for a binary tree.
Correct Answer: Preorder traversal
Explanation: Preorder traversal visits the root node first, then the left subtree, and finally the right subtree in a binary tree.
struct Node *insert(struct Node *root, int value) {
if (root == NULL)
return createNode(value);
if (value < root->data)
root->left = insert(root->left, value);
else if (value > root->data)
root->right = insert(root->right, value);
return root;
}
What operation does this function snippet perform?
Correct Answer: Insertion operation
Explanation: The function `insert` recursively inserts a value into a binary search tree (BST) maintaining its properties.
Correct Answer: Postorder traversal
Explanation: Postorder traversal visits the left subtree, then the right subtree, and finally the root node in a binary tree.
Correct Answer: Efficient insertion and deletion
Explanation: BSTs provide efficient O(log n) time complexity for insertion, deletion, and search operations, making them advantageous over arrays and linked lists for sorted data.
struct Node *search(struct Node *root, int key) {
if (root == NULL || root->data == key)
return root;
if (key < root->data)
return search(root->left, key);
return search(root->right, key);
}
What operation does this function snippet perform?
Correct Answer: Search operation
Explanation: The function `search` recursively searches for a key value in a binary search tree (BST) and returns the node if found, or NULL if not found.
Correct Answer: Level order traversal
Explanation: Level order traversal visits nodes level by level from left to right in a binary tree, starting from the root.
Correct Answer: Postorder traversal
Explanation: Postorder traversal of a binary expression tree visits the left subtree, right subtree, and then the root, which is suitable for generating a postfix expression.
struct Node *minValueNode(struct Node *node) {
struct Node *current = node;
while (current && current->left != NULL)
current = current->left;
return current;
}
What operation does this function snippet perform?
Correct Answer: Minimum value search
Explanation: The function `minValueNode` finds and returns the node with the minimum value in a binary search tree (BST).
Correct Answer: Search
Explanation: Search operation in a binary search tree (BST) has an average time complexity of O(log n), whereas in a binary tree, it can range up to O(n) depending on the tree structure.
struct Node *deleteNode(struct Node *root, int key) {
if (root == NULL) return root;
if (key < root->data)
root->left = deleteNode(root->left, key);
else if (key > root->data)
root->right = deleteNode(root->right, key);
else {
if (root->left == NULL) {
struct Node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL) {
struct Node *temp = root->left;
free(root);
return temp;
}
struct Node *temp = minValueNode(root->right);
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
return root;
}
What operation does this function snippet perform?
Correct Answer: Deletion operation
Explanation: The function `deleteNode` recursively deletes a node with the given key from a binary search tree (BST) while maintaining its properties.
Correct Answer: Inorder traversal
Explanation: Inorder traversal of a binary search tree (BST) produces a sorted list of elements in ascending order.
Correct Answer: Insertion
Explanation: Insertion in an unbalanced binary search tree (BST) can lead to worst-case time complexity of O(n), whereas balanced BSTs maintain O(log n) complexity for all operations.
int countNodes(struct Node *root) {
if (root == NULL)
return 0;
return 1 + countNodes(root->left) + countNodes(root->right);
}
What operation does this function snippet perform?
Correct Answer: Counting operation
Explanation: The function `countNodes` recursively counts and returns the number of nodes in a binary tree.
Correct Answer: Reverse inorder traversal
Explanation: Reverse inorder traversal visits the root node first, then the right subtree, and finally the left subtree in a binary tree.
Correct Answer: BST property
Explanation: The BST property ensures the ordering of nodes in a binary search tree, facilitating efficient search, insertion, and deletion operations.
int treeHeight(struct Node *root) {
if (root == NULL)
return 0;
int leftHeight = treeHeight(root->left);
int rightHeight = treeHeight(root->right);
return 1 + (leftHeight > rightHeight ? leftHeight : rightHeight);
}
What operation does this function snippet perform?
Correct Answer: Height calculation operation
Explanation: The function `treeHeight` recursively calculates and returns the height of a binary tree, which is the number of edges on the longest path from the root to a leaf node.
Correct Answer: Array
Explanation: Arrays are commonly used to represent graphs using adjacency matrices or adjacency lists in computer memory.
Correct Answer: Cycle
Explanation: A cycle in a graph is a path that starts and ends at the same vertex, traversing through other vertices and edges without repetition.
#define MAX_VERTICES 100
int graph[MAX_VERTICES][MAX_VERTICES];
void initGraph() {
int i, j;
for (i = 0; i < MAX_VERTICES; i++) {
for (j = 0; j < MAX_VERTICES; j++) {
graph[i][j] = 0;
}
}
}
What does this function snippet primarily do?
Correct Answer: Initializes an adjacency matrix for a graph
Explanation: The function `initGraph` initializes an adjacency matrix for a graph by setting all elements to 0, indicating no edges initially.
Correct Answer: Adjacency list
Explanation: Adjacency lists are more space-efficient for sparse graphs because they only store connections (edges) explicitly.
void addEdge(int u, int v) {
graph[u][v] = 1;
graph[v][u] = 1; // Assuming undirected graph
}
What operation does this function snippet perform?
Correct Answer: Insertion operation
Explanation: The function `addEdge` inserts an undirected edge between vertices `u` and `v` in an adjacency matrix representation of a graph.
Correct Answer: Adding a vertex
Explanation: Adding a vertex in an adjacency list representation is more efficient (O(1)) compared to an adjacency matrix (O(V^2)), especially for sparse graphs.
Correct Answer: Array of linked lists
Explanation: An adjacency list in C is typically implemented using an array of linked lists where each array element represents a vertex and the linked list contains its adjacent vertices.
void printGraph(int vertices) {
int i;
for (i = 0; i < vertices; i++) {
struct Node *temp = graph[i];
printf("Adjacency list of vertex %d\n", i);
while (temp) {
printf(" -> %d", temp->vertex);
temp = temp->next;
}
printf("\n");
}
}
What does this function snippet primarily do?
Correct Answer: Prints an adjacency list representation of a graph
Explanation: The function `printGraph` prints the adjacency list representation of a graph, showing each vertex and its adjacent vertices.
Correct Answer: Adjacency matrix
Explanation: Adjacency matrices are more suitable for dense graphs with many edges because they directly represent all possible edges between vertices.
Correct Answer: Depth-first search (DFS)
Explanation: DFS is commonly used for traversing or searching in graphs, exploring as far as possible along each branch before backtracking, making it useful for finding connected components.