Two-way / bidirectional Dictionary in C?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
A two-way or bidirectional dictionary is a data structure that allows efficient lookups in both directions. In a standard dictionary, you can typically map keys to values, but with a two-way dictionary, you can also efficiently retrieve keys given their values. This can be extremely useful in situations where you need quick, reversible lookups without the need for two separate dictionaries. In C#, you can implement a two-way dictionary using various techniques, including custom classes and data structures.
Implementation
In C#, we can implement a two-way dictionary using two standard dictionaries from the System.Collections.Generic
namespace: one for key-to-value mapping and another for value-to-key mapping. This ensures both forward and reverse lookup capabilities. Here's a simple implementation example:
- Add: Adds a new key-value pair. Ensures that neither the key nor the value already exists, maintaining unique bidirectional mapping.
- TryGetByFirst: Attempts to retrieve a value based on a provided key.
- TryGetBySecond: Attempts to retrieve a key based on a provided value.
- RemoveByFirst: Removes a mapping by its key, also cleaning the reverse dictionary.
- RemoveBySecond: Removes a mapping by its value, ensuring the forward dictionary is also cleaned.
- Count: Provides the total number of elements.
- Space Complexity: A bi-directional dictionary requires additional space to maintain two dictionaries internally, effectively doubling the storage requirement compared to a standard dictionary (
O(n)space complexity). - Time Complexity: The primary operations (add, lookup, remove) generally run in constant time (
O(1)) because they rely on a pair of hash tables. - Bidirectional Data Mapping: Where you need to frequently switch between key and value lookups, e.g., for encoding/decoding processes.
- Graph Algorithms: Especially when nodes are uniquely identified by alternate representations.
- Networking or User Identity Systems: Providing efficient lookups between usernames and user IDs.
- Unique Constraint: Both keys and values must be unique. This can be restrictive in scenarios where duplicate values (or keys) are needed.
- Memory Usage: They use more memory than single-direction dictionaries due to the dual storage.
- Concurrency: This implementation does not handle concurrent access. If you're operating in a multithreaded context, consider using concurrent data structures or locking mechanisms.
Related reading
- Two elements in array whose xor is maximum
- Type List vs type ArrayList in Java
- type mismatch error, expected type LIST for querying a one-to-many relationship in AppSync
- TypeError only integer scalar arrays can be converted to a scalar index with 1D numpy indices array
- Type or namespace name does not exist
- TypeLoadException says ''no implementation'', but it is implemented
- TypeError unhashable type 'dict
- Ukkonen's suffix tree algorithm in plain English

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.