

























































Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
COMP 352: Data Structures and Algorithms – Exam Prep Guide – Data Structures and Algorithms Exam Period: Final Examination Content: This 150-question exam bank comprehensively covers the core topics of COMP 352. The material is aligned with standard computer science curricula for second-year data structures and algorithms courses, with emphasis on the key concepts frequently tested in midterm and final examinations. Each question includes the correct answer and a detailed rationale. Suitable for students preparing for exams at Concordia University or similar institutions.
Typology: Exams
1 / 65
This page cannot be seen from the preview
Don't miss anything!


























































Course: COMP 352 – Data Structures and Algorithms Institution: Concordia University Exam Period: Final Examination Content: This 150-question exam bank comprehensively covers the core topics of COMP 352. The material is aligned with standard computer science curricula for second-year data structures and algorithms courses, with emphasis on the key concepts frequently tested in midterm and final examinations. Each question includes the correct answer and a detailed rationale. Suitable for students preparing for exams at Concordia University or similar institutions.
Description: This section covers the foundational data structures of the course: arrays, linked lists, stacks, and queues. Questions focus on operations, time complexities, implementations, and practical applications.
1. Which of the following operations can be performed in O(1) time on a singly linked list if you have a pointer to the node to be deleted? A) Delete the last node B) Insert a new node after a given node C) Delete a node with a given value (no pointer provided) D) Delete the node after a given node Answer: D Rationale: Deleting the node after a given node requires only updating the next pointer of the given node to skip the target node and pointing to the node after it. This is a constant-time operation because you have direct access to the node preceding the one you want to delete. The actual node to
be removed is identified in O(1). Inserting after a node is also O(1). Deletion of an arbitrary node without a pointer requires a traversal (O(n)). Text Reference: CLRS 3rd ed., Chapter 10.2, “Linked Lists.”
2. What is the main advantage of a doubly linked list over a singly linked list? A) It requires less memory. B) It simplifies deletion of a given node when you have a pointer to it. C) It allows for faster traversal in the forward direction. D) It eliminates the need for a head pointer. Answer: B Rationale: In a doubly linked list, each node contains pointers to both the next and the previous node. Therefore, when you have a pointer to a specific node, you can delete it in O(1) time by updating the next pointer of its predecessor and the previous pointer of its successor. In a singly linked list, you would need a pointer to the predecessor node, which would require a traversal from the head. The memory requirement is higher (extra prev pointer). Forward traversal speed is similar. Text Reference: CLRS 3rd ed., Chapter 10.2, “Linked Lists.” 3. A queue is characterized by which property? A) Last-In-First-Out (LIFO) B) First-In-First-Out (FIFO) C) Elements are accessed by key D) Elements are stored contiguously Answer: B Rationale: A queue is an abstract data type (ADT) that follows the FIFO ordering principle. Elements are added (enqueued) at the rear and removed (dequeued) from the front. Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 6. “Stacks, Queues, and Deques.”
C) O(1) amortized D) O(1) worst-case Answer: C Rationale: When implementing a queue with a circular array, both enqueue (add at tail) and dequeue (remove from head) operations update indices in O(1) time. However, when the underlying array is full, enqueue may require a resize operation (copying all elements), which takes O(n) time. Such resizing occurs rarely, making the amortized time complexity O(1) for each operation. Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 6.3, “Implementing a Queue with a Circular Array.”
7. When implementing a queue using a singly linked list, what is the typical implementation strategy for efficient operations? A) enqueue at head, dequeue at head B) enqueue at tail, dequeue at head C) enqueue at head, dequeue at tail D) enqueue at tail, dequeue at tail Answer: B Rationale: To have both enqueue and dequeue operations in O(1) time, the most effective approach is to maintain two pointers: one to the head (front) and one to the tail (rear). New elements are enqueued at the tail (O(1) with a tail pointer). Elements are dequeued from the head (O(1)). Both operations require O(1) time. The other options would involve traversing the list to find the appropriate end, resulting in O(n) time for one of the operations. 8. Which data structure is best suited for a “Round-Robin” scheduling algorithm in an operating system? A) Stack B) Priority queue C) Queue D) Array Answer: C
Rationale: Round-Robin scheduling assigns a fixed time slice (quantum) to each process in cyclic order. A FIFO queue is ideal because processes are added to the ready queue and the scheduler picks the first process from the front to run. If a process does not finish within its quantum, it is placed back at the end of the queue. Text Reference: Silberschatz, Galvin, Gagne, “Operating System Concepts,” Chapter 5, “CPU Scheduling.”
9. What is the time complexity of searching for an element in a sorted array using binary search? A) O(n) B) O(log n) C) O(n²) D) O(n log n) Answer: B Rationale: Binary search leverages the sorted order to divide the search interval in half repeatedly. Each comparison eliminates half of the remaining elements. The number of operations required to find the target or determine it is not present is proportional to log₂(n), resulting in O(log n) complexity. Text Reference: CLRS 3rd ed., Chapter 2.1, “Insertion Sort.” 10. What is the major disadvantage of using a simple linked list for implementing a queue when compared to a circular array? A) Higher memory usage (extra pointer per node) B) Slower amortized enqueue time C) Cannot handle large sizes D) Difficult to implement Answer: A Rationale: In a linked list implementation of a queue, each node stores both the data and a pointer to the next node. This additional pointer per element incurs a memory overhead. In contrast, a circular array requires memory only for the elements and two integer indices. Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 6.3, “Implementing a Queue with a Circular Array.”
Answer: C Rationale: Step-by-step execution: push(5): stack = [5] push(10): stack = [5,10] pop(): removes 10, returns 10 push(15): stack = [5,15] pop(): removes 15, returns 15 pop(): removes 5, returns 5 The pop outputs are 10, 15, 5, which corresponds to option B? Wait, the question likely asks for the output of the pop operations or the final stack? Let's clarify. The sequence of pop outputs: first pop gives 10, second pop gives 15, third pop gives 5. So the output is 10, 15, 5. That matches option B. But the final stack would be empty. So answer B. Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 6. “Stacks.”
14. What is the space complexity of a singly linked list with n nodes? A) O(n²) B) O(n) C) O(log n) D) O(1) Answer: B Rationale: The singly linked list consists of n nodes, each containing data and a single pointer. The total memory used grows linearly with the number of elements. Therefore, the space complexity is O(n). This is optimal for a structure that must store n elements.
15. Which of the following is true about a queue? A) Dequeue removes the most recently added element. B) Enqueue adds an element to the front. C) Dequeue removes the element that has been in the queue the longest. D) The element added first is removed last. Answer: C Rationale: A queue is a FIFO (First In, First Out) data structure. The dequeue operation removes the element that has been in the queue the longest (the front element). New elements are added to the rear with the enqueue operation. Option C is correct; option D describes a stack. 16. Which data structure is used to implement function calls in most programming languages? A) Heap B) Queue C) Stack D) Array Answer: C Rationale: Function call management (the call stack) is a classic application of a stack. When a function is called, a new activation record (frame) containing local variables, parameters, and the return address is “pushed” onto the call stack. When the function returns, its frame is “popped” off the stack, and control returns to the previous function. Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 6. “Stacks.” 17. What is the main disadvantage of using a simple (non-circular) array to implement a queue? A) Dequeue is always O(n). B) The array size cannot be changed. C) Over time, the front index moves forward, creating unused space at the beginning of the array. D) Both B and C.
O(n) time complexity for indexed access. Arrays support O(1) random access.
20. In a stack implemented with a singly linked list, if we push elements at the head, what is the time complexity of push and pop? A) O(n) for both B) O(1) for push and O(1) for pop C) O(1) for push and O(n) for pop D) O(n) for push and O(1) for pop Answer: B Rationale: Both push and pop can be implemented in O(1) time on a singly linked list if we always operate on the head node. Push creates a new node, makes it point to the current head, and then updates head to this new node. Pop saves the data of the head node, updates head to head.next, and deletes the old head node. Both operations involve only a constant number of steps. 21. Which of the following abstract data types (ADTs) allows insertion and deletion only at the ends? A) Stack B) Queue C) Deque D) Both A and B Answer: D Rationale: A stack allows insertion and deletion only at the top (one end). A queue allows insertion at the rear and deletion from the front (both ends, but specific ends). Therefore, both stacks and queues restrict operations to the ends. A deque (double-ended queue) allows insertion and deletion at both ends.
22. What is the best case time complexity for inserting an element into an unsorted array? A) O(1) B) O(n) C) O(log n) D) O(n²) Answer: A Rationale: In an unsorted array, an element can be inserted at the end of the array without any comparisons or rearrangements (assuming the array has available capacity). This operation can be performed in constant time O(1). This is one of the advantages of using an unsorted array for dynamic sets when order is not important. Text Reference: CLRS 3rd ed., Chapter
C) (rear + 2) % N == front D) rear == front + 1 Answer: B Rationale: In the common array-based queue implementation where one array cell is left unused, the queue is considered full when (rear + 1) % N == front. This condition indicates that the next enqueue operation would make the queue “wrap” and catch up with the front, which is prevented to avoid ambiguity with the empty condition (front == rear). Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 6.3, “Implementing a Queue with a Circular Array.”
27. What is the time complexity for inserting an element at the front of a dynamic array (ArrayList) if the array has unused capacity? A) O(1) B) O(n) C) O(log n) D) O(n²) Answer: B Rationale: In a dynamic array (ArrayList), inserting an element at the front requires shifting all existing elements to the right by one position to make space at index 0. This requires O(n) time, where n is the number of elements already in the list. Even if there is unused capacity, the shift operation must be performed. The only way to achieve O(1) insertion at the front is to use a linked list. 28. Which abstract data type is best for implementing a buffer in a multimedia streaming application (producer-consumer problem) where data is produced at one rate and consumed at another? A) Stack B) Queue C) Priority Queue D) Hash Table Answer: B
Rationale: A queue is the classic data structure for the producer-consumer problem. Producers add data to one end (enqueue), and consumers remove data from the other end (dequeue). This FIFO behavior ensures that data is processed in the order it was produced. Queues handle rate mismatches by allowing the buffer to grow (within limits) during times when producers outpace consumers and shrink when consumers catch up.
29. Which of the following statements about linked lists is FALSE? A) They can grow and shrink dynamically. B) They support O(1) insertion and deletion at any known position. C) They consume extra memory for pointers. D) They support random access to elements by index. Answer: D Rationale: Linked lists do not support random access by index. To access the i-th element, you must traverse from the head (or tail) node by node, which is O(n). This is a key difference from arrays. The other statements are true: linked lists are dynamic, insertion/deletion at a known position is O(1), and extra memory is needed for pointers. 30. A deque (double-ended queue) allows which of the following operations? A) Push and pop at both ends. B) Only push at one end and pop at the other. C) Only pop at both ends. D) Only push at both ends. Answer: A Rationale: A deque is a generalization of both stacks and queues. It supports insertion and deletion at both the front and the back ends. Common operations are addFirst, addLast, removeFirst, removeLast. This flexibility makes deques useful for certain algorithms, such as the sliding window maximum problem.
Rationale: Quick sort achieves its worst-case performance (O(n²)) when the pivot selection leads to highly unbalanced partitions. If a naive pivot strategy (e.g., always choosing the first element) is used, a sorted or reverse sorted input will produce the worst behavior. With better pivot strategies (random, median-of-three), the probability of worst-case behavior becomes very low. Text Reference: CLRS 3rd ed., Chapter 7.2, “Performance of Quicksort.”
33. Which of the following sorting algorithms is considered “stable”? A) Quick sort B) Heap sort C) Merge sort D) Selection sort Answer: C Rationale: Stable sorting algorithms maintain the relative order of records with equal keys (values). Merge sort is inherently stable (if implemented carefully in the merge step). Quick sort is typically not stable, and heap sort is not stable. Selection sort is not stable. Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 12. “Sorting and Selection.” 34. Which sorting algorithm is often the best choice for sorting a very large dataset that does not fit entirely in memory (external sorting)? A) Quick sort B) Heap sort C) Merge sort D) Counting sort Answer: C Rationale: Merge sort is frequently used for external sorting because its divide-and-conquer nature allows it to sort chunks of data that fit in memory and then merge the sorted chunks efficiently. This is the basis for external merge sort. Quick sort and heap sort are not as suitable because they
require more random access, which is inefficient for disk-based data. Text Reference: CLRS 3rd ed., Chapter 18. “B-Trees.” (Not directly in the main textbook, but external sorting is a standard topic; covered in many external memory algorithm resources.)
35. Which of the following is NOT an in-place sorting algorithm? A) Heap sort B) Quick sort (standard implementation) C) Merge sort (standard implementation) D) Insertion sort Answer: C Rationale: The standard implementation of merge sort requires O(n) auxiliary space for the merging process. Heap sort, quick sort (with in-place partitioning), and insertion sort can all be implemented to use O(1) extra space. Text Reference: Goodrich et al., “Data Structures and Algorithms in Python,” Chapter 12. “Sorting and Selection.” 36. What is the time complexity of insertion sort in its worst case? A) O(n) B) O(n log n) C) O(n²) D) O(1) Answer: C Rationale: Insertion sort’s worst-case occurs when the input is sorted in reverse order. In this case, each insertion requires shifting all previously sorted elements, leading to approximately n²/2 comparisons and moves, giving O(n²) time complexity. The best case (already sorted) is O(n). Text Reference: CLRS 3rd ed., Chapter 2.1, “Insertion Sort.”
stable, not adaptive (it always uses the heap structure, regardless of input order), and its best-case time complexity is O(n log n). Text Reference: CLRS 3rd ed., Chapter 6, “Heapsort.”
40. In a merge sort implementation, which operation dominates the overall runtime? A) Splitting the arrays B) Recursive calls C) The merging process D) The base case checks Answer: C Rationale: The merging process dominates the runtime because it requires linear work at each level of recursion (O(n) per level), and there are O(log n) levels, resulting in O(n log n) total. The splitting is O(1) per recursive call. The number of recursive calls is O(n), but the work done per call is dominated by merging. 41. For an input array that is already sorted, which of the following sorting algorithms would perform best? A) Quick sort (with a naive pivot selection) B) Heap sort C) Insertion sort D) Merge sort Answer: C Rationale: Insertion sort has a best-case time complexity of O(n) for already sorted input because each new element is already in its correct position (only one comparison per element). Quick sort with a naive pivot (e.g., always first) would perform poorly on sorted input (O(n²)). Heap sort and merge sort maintain O(n log n) regardless of order. Text Reference: CLRS 3rd ed., Chapter 2.1, “Insertion Sort.”
42. The “divide and conquer” strategy is used by which of the following sorting algorithms? A) Quick sort and merge sort B) Bubble sort C) Insertion sort D) Selection sort Answer: A Rationale: Both quick sort and merge sort are classic examples of the divide-and-conquer paradigm. Quick sort partitions the array around a pivot and then recursively sorts the sub-arrays. Merge sort divides the array into two halves, recursively sorts them, and then merges the sorted halves. Bubble sort, insertion sort, and selection sort are iterative algorithms. 43. What is the time complexity of counting sort when the range of input values (k) is significantly larger than the number of elements (n)? A) O(n) B) O(n + k) C) O(k log n) D) O(n log n) Answer: B Rationale: The time complexity of counting sort is O(n + k), where k is the range of possible input values (max – min + 1). If k is much larger than n, the complexity is dominated by O(k), which can be worse than O(n log n). Counting sort is most effective when k is O(n). Text Reference: CLRS 3rd ed., Chapter 8.2, “Counting Sort.” 44. Which sorting algorithm is the most suitable for sorting a singly linked list? A) Quick sort B) Merge sort C) Heap sort D) Counting sort