Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 16

Choosing the Right Tool: Hash Tables vs. BSTs

Recommended resources

Hello! Welcome to the final lesson in our module on Hashing, Trees, and Search.

In previous lessons, you've done the deep-dive work of implementing and analyzing hash tables and binary search trees. You understand their internal mechanics, from collision resolution strategies in hash tables to the rebalancing rotations in AVL trees. Now, we shift our focus from "how" to "why" and "when."

Your goal for this lesson is to apply a hash table or a BST to solve a problem, justifying the choice of data structure. This is a critical skill for moving from a developer's mindset to an architect's. An architect's primary job is often not to write the code but to choose the right tools and patterns that enable the code to be efficient, scalable, and maintainable. This lesson is a direct step toward that goal. We will analyze a problem, evaluate both data structures as potential solutions, and build a framework for making a justified decision.

1. A Problem to Solve: Finding the Odd One Out

Let's start with a classic problem. Imagine you are given an array of integers where every number appears an even number of times, except for one number which appears an odd number of times. Your task is to find that unique number.

For example, in the array [1, 4, 6, 4, 1, 9, 6], the number 9 appears once (odd), while 1, 4, and 6 each appear twice (even). The answer is 9.

How would you approach this? Let's analyze two solutions, one using a hash table and one using a BST.


2. The Hash Table Approach

A hash table is a natural fit for any problem involving frequency counting. The general idea is to map each unique number to its count.

The following video demonstrates a whiteboard interview session where this exact problem is solved using a hash map. It's a great example of the thought process involved in developing and refining an algorithmic solution.

Whiteboard Interview with Arrays and Hash Maps - Whiteboard Wednesday

Watch this video from Irfan Baqui to see how a hash map can be used to solve the 'odd occurrence' problem. Pay attention to the initial approach and how it's refined for better space efficiency.

Watch from 00:40 to 07:15, and then from 11:21 to 15:08. The first part covers the problem clarification and the initial counting approach. The second part presents a more optimized implementation.

As you saw, the hash table strategy is very effective:

  1. Iterate through the array: For each number...
  2. Use the hash table to track occurrences:
    • If the number is already a key in the hash table, you've seen it before.
    • If it's not, it's the first time you're seeing it.
  3. Update the count: The initial idea is to store number -> count. An optimized version, as shown in the video, is to add the number to the hash set on its first appearance and remove it on its second. This way, any number appearing an even number of times will be added and then removed, ultimately leaving only the number that appeared an odd number of times.

Complexity Analysis (Hash Table):

  • Time Complexity: . You iterate through the array once. Each hash table operation (insertion, lookup, deletion) takes average time of .
  • Space Complexity: , where is the number of unique elements in the array. In the worst case (all elements are unique), this is .

3. The Binary Search Tree Approach

Now, how would we solve the same problem with a Binary Search Tree? Since a BST can also store key-value pairs (where the node's key is the number and you could add a count property to the node), the logic would be similar:

  1. Iterate through the array: For each number...
  2. Search the BST: Look for a node containing the number.
    • If the node is found, increment its count.
    • If it's not found, insert a new node with the number and a count of 1.
  3. Final Scan: After processing the whole array, you would need to traverse the BST to find the node with an odd count.

Complexity Analysis (BST):

  • Time Complexity: , where is the number of unique elements. You iterate through the array ( times), and for each element, you perform a search/insert operation on the BST, which takes time (assuming a balanced tree).
  • Space Complexity: , as you store one node for each unique element.

For this specific problem, the hash table's time complexity is clearly superior to the BST's . But does this mean hash tables are always better? Absolutely not. The choice of data structure depends entirely on the problem's requirements.


4. The Justification: A Framework for Choosing

The "odd occurrence" problem did not leverage the key advantage of a BST: its sorted nature. Let's build a framework to help you decide when to use each data structure.

The article "Binary Search Trees vs Hash Maps" provides an excellent summary of the core criteria.

Binary Search Trees vs Hash Maps: Implementation, ...

This article provides a fantastic, direct comparison of BSTs and Hash Maps. We will focus on the section that explicitly lists the criteria for choosing one over the other.

Read the section 'When to Choose Which Data Structure'. This provides a clear, actionable checklist that we will use as the foundation of our decision-making framework.

Based on that reading and our previous knowledge, we can establish a set of questions you should ask yourself when designing a system:

Question If 'Yes', lean towards... Rationale
1. Is near-instantaneous lookup/insertion/deletion for exact keys the top priority? Hash Table Its average-case complexity for these operations is unmatched. This is ideal for caches, dictionaries, and frequency counters.
2. Do you need to process elements in a sorted order? Binary Search Tree A simple in-order traversal of a BST yields all elements in sorted order with complexity. A hash table is unordered; sorting its elements would be a separate, more expensive step.
3. Do you need to perform range queries (e.g., "find all users with an age between 25 and 35")? Binary Search Tree The sorted structure of a BST makes range searches very efficient. You can navigate to the start of the range and traverse until you exceed the end. A hash table would require iterating through every single element to check if it's in the range.
4. Do you need to find the minimum/maximum element, or the closest element to a given value? Binary Search Tree These operations are efficient in a BST. Finding the minimum is a matter of traversing all the way to the left, and the maximum is all the way to the right. A hash table provides no such mechanism.
5. Is a predictable, guaranteed upper-bound on performance critical (e.g., real-time systems)? Balanced BST A self-balancing BST (like AVL or Red-Black) guarantees for its operations. A hash table's performance can degrade to in the worst case (many collisions) and can experience significant latency spikes during resizing/rehashing.

This Stack Overflow discussion provides additional real-world context, particularly regarding how databases use these structures.

Hash Table with Open Hashing (Chaining)
A hash table, often implemented with chaining as shown here, excels at fast, direct lookups but provides no inherent order.
Binary Tree vs. Binary Search Tree Comparison
A Binary Search Tree (right) maintains a strict order, enabling efficient range queries and sorted traversals, unlike a general binary tree (left) or a hash table.

A great example is database indexing. As mentioned in the Stack Overflow thread and the article on enterprise applications, databases use both!

  • A hash index is used for fast equality checks (e.g., WHERE user_id = 123).
  • A B-Tree index (a variant of a BST) is used for range queries (e.g., WHERE price BETWEEN 100 AND 200).

This hybrid approach demonstrates that the best architects use the right tool for the specific job at hand.

Test your understanding!

You are designing a leaderboard for a gaming application. The system needs to perform two main operations millions of times per hour:

  1. Update a player's score: Given a playerID and a new score.
  2. Fetch the Top 100 players: Return a list of the 100 players with the highest scores, sorted in descending order.

Would you use a hash table or a BST as your primary data structure to store the playerID -> score mapping? Justify your choice based on the framework above.

Show answer

This is a tricky question that highlights the trade-offs. Let's analyze it.

  • Updating a score: This is a direct key-based lookup (playerID). A hash table would be extremely fast for this at . A BST would be . The hash table has an edge here.
  • Fetching the Top 100: This requires finding the 100 maximum values, which is a form of range/order-based query. A BST excels at this. You could, for example, do a reverse in-order traversal and stop after 100 players. In a hash table, you would have to extract all n players and then sort them, which would be very inefficient ().

Justification:

A Binary Search Tree is the better choice for the primary data structure here. While the updates are slightly slower ( vs. ), the cost of fetching the top players using a hash table is prohibitive. The BST provides an excellent balance, making both operations efficient enough. The critical requirement of fetching an ordered subset of data strongly points towards a data structure that maintains order internally.

(Note: In a real-world system, you might even use a more specialized structure like a Skip List or a composite structure involving a hash map for lookups and a balanced BST/heap for ordering, but between these two basic options, the BST is the clear winner.)


Conclusion

You've now reached a new level of data structure analysis. It's not just about knowing how an algorithm works, but about being able to weigh its trade-offs against others to make an informed, defensible architectural decision.

Key Takeaways:

  • The choice between a hash table and a BST is a classic trade-off between speed for unordered access and flexibility for ordered access.
  • Hash tables are ideal when your primary use case is fast, key-based lookups, insertions, and deletions, and you don't care about the order of elements.
  • BSTs are the superior choice when you need to maintain sorted order, perform range queries, or find min/max/closest elements efficiently.
  • Real-world systems often use hybrid approaches, leveraging the strengths of multiple data structures to meet complex requirements.

This concludes our module on Hashing, Trees, and Search. You have built a strong foundation, moving from basic implementations to complex analysis and architectural decision-making.

In our next module, "Advanced Structures: Heaps and Graphs," we will expand our toolkit. You'll learn about heaps, which are perfect for priority-based problems like the leaderboard example, and graphs, which are essential for modeling and solving problems involving networks and complex relationships.