답변:
그것들은 매우 다른 방식으로 구현됩니다.
hash_map
( unordered_map
TR1 및 Boost에서는 대신 사용) 키가 테이블의 슬롯에 해시되고 값이 해당 키에 연결된 목록에 저장되는 해시 테이블을 사용합니다.
map
균형 이진 검색 트리 (일반적으로 빨강 / 검정 트리)로 구현됩니다.
unordered_map
는 컬렉션의 알려진 요소에 액세스 하는 데 약간 더 나은 성능을 제공해야하지만 map
추가 유용한 특성이 있습니다 (예 : 정렬 된 순서로 저장되어 처음부터 끝까지 순회 할 수 있음). unordered_map
삽입 및 삭제가 map
.
hash_map
많은 라이브러리 구현에서 제공하는 공통 확장입니다. 이것이 바로 unordered_map
TR1의 일부로 C ++ 표준에 추가되었을 때로 이름이 변경된 이유 입니다. map은 일반적으로 red-black 트리와 같은 균형 잡힌 이진 트리로 구현됩니다 (구현은 물론 다양합니다). hash_map
그리고 unordered_map
일반적으로 해시 테이블로 구현됩니다. 따라서 순서가 유지되지 않습니다. unordered_map
삽입 / 삭제 / 쿼리는 O (1) (일정 시간)이며 여기서 맵은 O (log n)입니다. 여기서 n은 데이터 구조의 항목 수입니다. 따라서 unordered_map
더 빠르며 항목의 순서에 신경 쓰지 않으면 map
. 때때로 당신은 질서를 유지하기를 원하며 (키로 정렬) 그것이 map
선택이 될 것입니다.
주요 차이점 중 일부는 복잡성 요구 사항에 있습니다.
A map
는 Red-Black Tree 데이터 구조 O(log(N))
로 구현되므로 삽입 및 찾기 작업에 시간이 필요합니다 .
은 unordered_map
의 '평균'시간이 필요 O(1)
삽입 및 발견을위한, 그러나의 최악의 시간을 가질 수있다 O(N)
. Hash Table 데이터 구조를 사용하여 구현 되었기 때문 입니다.
따라서 일반적 unordered_map
으로 더 빠르지 만 저장하는 키와 해시 함수에 따라 훨씬 더 나빠질 수 있습니다.
C ++ 사양은 STL 컨테이너에 사용해야하는 알고리즘을 정확히 말하지 않습니다. 그러나 성능에 특정 제약을 두어 map
및 기타 연관 컨테이너에 대한 해시 테이블 사용을 배제합니다 . (가장 일반적으로 레드 / 블랙 트리로 구현됩니다.) 이러한 제약 조건은 해시 테이블이 제공 할 수있는 것보다 이러한 컨테이너에 대해 더 나은 최악의 경우 성능을 요구합니다.
그러나 많은 사람들이 실제로 해시 테이블을 원하므로 해시 기반 STL 연관 컨테이너는 수년 동안 일반적인 확장이었습니다. 결과적으로 그들은 unordered_map
C ++ 표준의 최신 버전에 추가되었습니다 .
map
는 일반적으로 균형 잡힌 btree가 operator<()
위치를 결정하는 수단으로 사용했기 때문이라고 생각했습니다 .
map
의 모든 멤버 가 정렬되어 있으므로 balanced binary search tree
(일반적으로 a rb_tree
) 에서 구현 balanced binary search tree
됩니다.
hash_map
의 hashtable
모든 구성원 hashtable
이 정렬되지 않았으므로의 구성원이 정렬되지 않았으므로 hash_map(unordered_map)
.
hash_map
은 C ++ 표준 라이브러리가 아니지만 이제 이름이 unordered_map
( 이름이 바뀐 것으로 생각할 수 있음) C ++ 11 이후로 C ++ 표준 라이브러리가됩니다.이 질문을 참조하십시오. hash_map과 unordered_map의 차이점? 자세한 내용은.
아래에서는 두 유형 맵이 구현되는 방법에 대한 소스 코드의 핵심 인터페이스를 제공합니다.
아래 코드는지도가의 래퍼 일 뿐이며 balanced binary search tree
거의 모든 함수가 함수를 호출하는 것임을 보여줍니다 balanced binary search tree
.
template <typename Key, typename Value, class Compare = std::less<Key>>
class map{
// used for rb_tree to sort
typedef Key key_type;
// rb_tree node value
typedef std::pair<key_type, value_type> value_type;
typedef Compare key_compare;
// as to map, Key is used for sort, Value used for store value
typedef rb_tree<key_type, value_type, key_compare> rep_type;
// the only member value of map (it's rb_tree)
rep_type t;
};
// one construct function
template<typename InputIterator>
map(InputIterator first, InputIterator last):t(Compare()){
// use rb_tree to insert value(just insert unique value)
t.insert_unique(first, last);
}
// insert function, just use tb_tree insert_unique function
//and only insert unique value
//rb_tree insertion time is : log(n)+rebalance
// so map's insertion time is also : log(n)+rebalance
typedef typename rep_type::const_iterator iterator;
std::pair<iterator, bool> insert(const value_type& v){
return t.insert_unique(v);
};
hash_map
:hash_map
hashtable
구조는 다음과 같이 구현됩니다 .
아래 코드에서 나는의 주요 부분 hashtable
을 제공하고 hash_map
.
// used for node list
template<typename T>
struct __hashtable_node{
T val;
__hashtable_node* next;
};
template<typename Key, typename Value, typename HashFun>
class hashtable{
public:
typedef size_t size_type;
typedef HashFun hasher;
typedef Value value_type;
typedef Key key_type;
public:
typedef __hashtable_node<value_type> node;
// member data is buckets array(node* array)
std::vector<node*> buckets;
size_type num_elements;
public:
// insert only unique value
std::pair<iterator, bool> insert_unique(const value_type& obj);
};
마찬가지로 map's
단지 구성원 인 rb_tree
의 hash_map's
유일한 구성원입니다 hashtable
. 다음과 같은 주요 코드입니다.
template<typename Key, typename Value, class HashFun = std::hash<Key>>
class hash_map{
private:
typedef hashtable<Key, Value, HashFun> ht;
// member data is hash_table
ht rep;
public:
// 100 buckets by default
// it may not be 100(in this just for simplify)
hash_map():rep(100){};
// like the above map's insert function just invoke rb_tree unique function
// hash_map, insert function just invoke hashtable's unique insert function
std::pair<iterator, bool> insert(const Value& v){
return t.insert_unique(v);
};
};
아래 이미지는 hash_map에 53 개의 버킷이 있고 일부 값을 삽입하는 경우 내부 구조입니다.
아래 이미지는 map과 hash_map (unordered_map)의 차이점을 보여줍니다. 이미지는 How to choose between map and unordered_map? :
나는 무엇을 제공하는지 모르겠지만 hash_map은 150K의 부호없는 정수 키와 부동 값을 지우는 데 20 초 이상 걸립니다. 나는 다른 사람의 코드를 실행하고 읽고 있습니다.
이것이 hash_map을 포함하는 방법입니다.
#include "StdAfx.h"
#include <hash_map>
여기에서 읽었습니다 https://bytes.com/topic/c/answers/570079-perfomance-clear-vs-swap
clear ()는 O (N)의 순서라고 말합니다. 나에게 그것은 매우 이상하지만, 그것이 바로 그 방식입니다.