2026-02-05
By the end of this lab session, you should be able to:
Submit your work for the following activities to xSITe and/or Gradescope (as specified on each slide):
Submit using xSITe Quiz. Total 25 marks.
Implement a Queue Using 2 Stacks:
Submit using Gradescope. Total 25 marks.
Submit using Gradescope. Total 25 marks.
Find the Majority Element in an Array Using a Hash Table:
Submit using Gradescope. Total 25 marks.
On the xSITe course page, navigate to Assessments → Quizzes → Week 04 Lab Exercise 1: MCQs.
Select the best answer for each of the following five questions. You may refer to your notes or the lecture slides.
Consider a singly linked list with \(n\) nodes. You are given a pointer to the head of the list, but no tail pointer.
Which of the following operations can be performed in \(\Theta(1)\) time?
Correct Answer: c
Reasoning:
Inserting at the beginning only requires updating the head pointer. All other operations require traversing the list and therefore take \(\Theta(n)\) time.
In a singly linked list, you are given a pointer to a node \(x\) that is not the last node in the list.
Which operation can be performed in \(\Theta(1)\) time?
Correct Answer: a
Reasoning:
Node \(x\) can be deleted in \(\Theta(1)\) time by copying the key and next pointer from \(x.next\) into \(x\), and bypassing the next node.
A hash table uses chaining with \(m\) slots and stores \(n\) keys. Assume simple uniform hashing, and let the load factor be \(\alpha = n / m\).
What is the average-case time for an unsuccessful search?
Correct Answer: c
Reasoning:
Under simple uniform hashing, the expected length of each chain is \(\alpha\). An unsuccessful search must scan the entire chain in the target slot. The total time required (including computing the hash function) is \(\Theta(1 + \alpha)\).
A hash table uses chaining to resolve collisions. Each table slot stores a pointer to the head of a linked list.
Which of the following statements is always true for a hash table using chaining?
Correct Answer: d
Reasoning:
In a hash table that uses chaining, each key is first mapped to one specific slot using the hash function. That slot contains a linked list, and the key is stored as a node in that list. Because every key is hashed once, and each key is inserted into exactly one list, a key cannot appear in more than one linked list, and it also cannot be stored outside the lists. So, each key is stored in exactly one linked list.
Why the other options are wrong:
The lists are not automatically kept in sorted order; keys are usually inserted wherever convenient (often at the head).
A list can be much longer than the average; the load factor is only an average, not a limit.
The number of linked lists is fixed by the table size, not by how many keys are stored.
What property should a “good” hash function \(h(k)\) have when mapping keys to an \(m\)-slot hash table?
Correct Answer: b
Reasoning:
A good hash function should distribute keys uniformly across all available slots to minimize collisions and ensure efficient access times. Clustering keys in specific slots would degrade performance.
A stack is a linear data structure that follows the Last In, First Out (LIFO) principle.

Stacks can be implemented using native C++ arrays or using libraries like <stack> in the Standard Template Library (STL).
A queue is a linear data structure that follows the First In, First Out (FIFO) principle.

Queues can be implemented using native C++ arrays or using libraries like <queue> in the Standard Template Library (STL).
Your task is to implement a queue using 2 stacks, s1 and s2.
You can find the template files on xSITe (.zip archive).
Complete the partial queue_using_2_stacks.cpp file. The make command will compile the project.
Implement the .enqueue() and .dequeue() methods of the Queue struct inside queue_using_2_stacks.cpp. Do NOT use std::queue in your implementation.
To receive credit for your work, upload your completed queue_using_2_stacks.cpp file to the Gradescope assignment titled Week 04 Lab Exercise 2: Implement a Queue Using 2 Stacks.
The idea is to use the stack s1 for enqueue operations and the stack s2 for dequeue operations.
s1.s2 is empty, pop all elements from s1 and push them onto s2.s2.Here is a visual explanation of the solution:

Given the head of a singly-linked list, your task is to implement a function that reverses this linked list iteratively.
You can find the template files on xSITe (.zip archive).
Complete the partial reverse_linked_list.cpp file. The make command will compile the project.
Implement the reverseList() function inside reverse_linked_list.cpp.
Do NOT use any built-in functions for reversing the list (e.g., std::reverse).
To receive credit for your work, upload your completed reverse_linked_list.cpp file to the Gradescope assignment Week 04 Lab Exercise 3: Reverse a Linked List.
The idea is to reverse the linked list by changing the next pointers of the nodes.
prev as nullptr, current as the head of the list, and next as nullptr.next = current->next.current->next = prev.prev and current pointers one step forward using prev = current and current = next.One of the ways to create a hash table in C++ is to use std::unordered_map. Here is an example:
#include <iostream>
#include <unordered_map>
int main() {
// Declare unordered_map
std::unordered_map<std::string, int> umap;
// Insert elements into unordered_map
umap["apple"] = 1;
umap["banana"] = 2;
umap["cherry"] = 3;
// Access elements
std::cout << "apple: " << umap["apple"] << '\n';
std::cout << "banana: " << umap["banana"] << '\n';
// Check if an element exists
if (umap.find("cherry") != umap.end()) {
std::cout << "cherry is in the map\n";
}
// Remove an element
umap.erase("banana");
// Iterate through the unordered_map
for (const auto& pair : umap) {
std::cout << pair.first << ": " << pair.second << '\n';
}
}Given an array of positive integers, your task is to implement a function that finds the majority element in this array using a hash table. An element is considered a majority element if it appears strictly more than n / 2 times in an array containing n elements.
If no majority element exists, then the function should return -1.
[1, 2, 2] — element 2 is the majority element, since it appears \(2 > 3/2\) times in the array.[1, 2, 3] — no majority element exists, -1 is returned.[5, 5, 5, 8, 8, 8] — no majority element exists, -1 is returned. Both 5 and 8 appear 3 times, but either of them should appear at least \(6/2 + 1 = 4\) times to be considered the majority element.You can find the template files on xSITe (.zip archive).
Complete the partial majority_element.cpp file. The make command will compile the project.
Implement the findMajority() function inside majority_element.cpp.
Do NOT use any built-in functions for finding the majority element (e.g., std::count). You may however use std::unordered_map to instantiate your hash table.
To receive credit for your work, upload your completed majority_element.cpp file to the Gradescope assignment titled Week 04 Lab Exercise 4: Find the Majority Element.
The idea is to use a hash table to count the occurrences of each element in the array and then determine the majority element.
std::unordered_map to store the count of each element.n / 2 threshold, return this element immediately.Week 04: Linked Lists and Hash Tables (Lab)