Is the unordered_map really unordered?

前端 未结 5 2035
悲哀的现实
悲哀的现实 2020-12-06 06:07

I am very confused by the name \'unordered_map\'. The name suggests that the keys are not ordered at all. But I always thought they are ordered by their hash value. Or is th

5条回答
  •  误落风尘
    2020-12-06 06:11

    In answer to your edited question, no those two snippets are not equivalent at all. std::map stores nodes in a tree structure, unordered_map stores them in a hashtable*.

    Keys are not stored in order of their "hash value" because they're not stored in any order at all. They are instead stored in "buckets" where each bucket corresponds to a range of hash values. Basically, the implementation goes like this:

    function add_value(object key, object value) {
       int hash = key.getHash();
    
       int bucket_index = hash % NUM_BUCKETS;
       if (buckets[bucket_index] == null) {
           buckets[bucket_index] = new linked_list();
       }
       buckets[bucket_index].add(new key_value(key, value));
    }
    
    function get_value(object key) {
       int hash = key.getHash();
    
       int bucket_index = hash % NUM_BUCKETS;
       if (buckets[bucket_index] == null) {
           return null;
       }
    
       foreach(key_value kv in buckets[bucket_index]) {
           if (kv.key == key) {
               return kv.value;
           }
       }
    }
    

    Obviously that's a serious simplification and real implementation would be much more advanced (for example, supporting resizing the buckets array, maybe using a tree structure instead of linked list for the buckets, and so on), but that should give an idea of how you can't get back the values in any particular order. See wikipedia for more information.


    * Technically, the internal implementation of std::map and unordered_map are implementation-defined, but the standard requires certain Big-O complexity for operations that implies those internal implementations

提交回复
热议问题