STL 관련 용기 값 hashtable
hashtable 명사
해시 함수: 특정한 요 소 를 색인 으로 표시 합 니 다.충돌 (collision): 서로 다른 요소 가 같은 위치 에 매 핑 됩 니 다.충돌 해결 방법: 선형 탐색 법, 2 차 탐색 법, 체인 열기 등.부하 계수: 요소 개 수 를 표 크기 로 나 눕 니 다.주 그룹: 평균 삽입 원가 의 성장 폭 은 부하 계수 의 성장 폭 보다 훨씬 높다.차 그룹: hashtable 이 2 차 탐 사 를 사용 하면 두 요소 가 hash function 을 통 해 계 산 된 위치 가 같 으 면 삽입 할 때 탐색 하 는 위치 도 같 고 어떤 낭 비 를 초래 합 니 다.체인 열기: 표 요소 마다 list 가 있 습 니 다.통 (bucket): hashtable 표 의 모든 요소 입 니 다.
hashtable 조직 방식
노드 클래스
template 
struct _Hashtable_node
{
  _Hashtable_node* _M_next;
  _Val _M_val;
};   hashtable 의 노드 는 list 노드 와 유사 합 니 다.하나의 Node 지침 은 모든 통 의 목록 의 첫 번 째 요 소 를 가리 키 며, 통 의 링크 의 첫 번 째 주 소 는 vector 벡터 에 저 장 됩 니 다.
typedef _Hashtable_node<_val> _Node;
vector<_node> _M_buckets;hashtable 교체 기의 자체 증가 연산 자 정 의 는 다음 과 같 습 니 다.
template 
_Hashtable_iterator<_val>&
_Hashtable_iterator<_val>::operator++()
{
  const _Node* __old = _M_cur;      //       
  _M_cur = _M_cur->_M_next;         //      
  if (!_M_cur) {                    //         ,            
    //            
    size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
    //    ,          ,       
    while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
        //                   
      _M_cur = _M_ht->_M_buckets[__bucket];    
  }
  return *this;
} hashtable 클래스 는 다섯 개의 템 플 릿 매개 변 수 를 정의 합 니 다.
template 
class hashtable; _Val 값 유형키 키 종류HashFcn 해시 함수ExtractKey 추출 키 의 방법EqualKey 판단 키 가 같은 방법Alloc 분배 기 종류
hashtable 삽입 동작
insert_unique 는 값 이 중복 되 는 삽입 을 허용 하지 않 습 니 다:
 pair insert_unique(const value_type& __obj)
  {
    resize(_M_num_elements + 1);
    return insert_unique_noresize(__obj);
  } 이 함 수 는 먼저 resize 함 수 를 호출 하여 현재 요소 에 1 의 값 을 추가 하여 확장 이 필요 한 지 확인 합 니 다.처리 완료 후 치obj 를 hashtable 에 삽입 합 니 다.resize 함수 의 정 의 는 다음 과 같 습 니 다.
template 
void hashtable<_val>
  ::resize(size_type __num_elements_hint)
{
  const size_type __old_n = _M_buckets.size();    //      
  if (__num_elements_hint > __old_n) {            //         
    //                __n
    const size_type __n = _M_next_size(__num_elements_hint);
    if (__n > __old_n) {                          //          :    
      //     __n(    )      
      vector<_node _all=""> __tmp(__n, (_Node*)(0),
                                 _M_buckets.get_allocator());
      __STL_TRY {
        //  hashtable     
        for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
          _Node* __first = _M_buckets[__bucket];        //         
          while (__first) {                             //           
            //              _M_val,      __n,
            //      hashtable     (rehash)
            size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
            //              ,             
            _M_buckets[__bucket] = __first->_M_next;
            
            //             ,       。
            //           hashtable              
            __first->_M_next = __tmp[__new_bucket];
            // hashtable,         __first
            __tmp[__new_bucket] = __first;
            //  __first    __first->_M_next,   hashtable             。
            __first = _M_buckets[__bucket];          
          }
        }
        //  hashtable       hash      
        _M_buckets.swap(__tmp);    //              。
        //       __tmp   ,       ,__tmp        ,         。
      }
      //             
#         ifdef __STL_USE_EXCEPTIONS
      catch(...) {
        //           
        for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
          //          
          while (__tmp[__bucket]) {
            _Node* __next = __tmp[__bucket]->_M_next;
            _M_delete_node(__tmp[__bucket]);    //      
            __tmp[__bucket] = __next;           //      
          }
        }
        throw;
      }
#         endif /* __STL_USE_EXCEPTIONS */
    }
  }
} insert_unique_noresize 의 함수 정 의 는 다음 과 같 습 니 다.
template 
pair::iterator, bool> 
hashtable<_val>
  ::insert_unique_noresize(const value_type& __obj)
{
  const size_type __n = _M_bkt_num(__obj);     //         ,      
  _Node* __first = _M_buckets[__n];            //       
    
  //      ,     
  for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) 
    //      __obj      
    if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
      //           ,         。  
      return pair(iterator(__cur, this), false);
  
  //                ,  
  _Node* __tmp = _M_new_node(__obj);    //       
  __tmp->_M_next = __first;             //             
  _M_buckets[__n] = __tmp;              //                 
  ++_M_num_elements;                    //  hashtable    
  //          ,         。
  return pair(iterator(__tmp, this), true);
}    결합 insert유 니 크 함수 에서 호출 된 두 함수 인터페이스의 분석 을 통 해 알 수 있 듯 이:
insert_equal 중복 삽입 허용:
  iterator insert_equal(const value_type& __obj)
  {
    resize(_M_num_elements + 1);
    return insert_equal_noresize(__obj);
  }insert유 니 크 비교, 함수 확장 후 중복 값 을 허용 하 는 비 확장 삽입 함수 insert 호출equal_noresize:
template 
typename hashtable<_val>::iterator 
hashtable<_val>
  ::insert_equal_noresize(const value_type& __obj)
{
  const size_type __n = _M_bkt_num(__obj);        //         ,      
  _Node* __first = _M_buckets[__n];               //        
  ///      ,       
  for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) 
    //      __obj      ,          
    if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
      _Node* __tmp = _M_new_node(__obj);        //       
      __tmp->_M_next = __cur->_M_next;          //                   
      __cur->_M_next = __tmp;                   //              
      ++_M_num_elements;                        //      
      return iterator(__tmp, this);             //      ,  
    }
    
  //                
  _Node* __tmp = _M_new_node(__obj);            //       
  __tmp->_M_next = __first;                     //             
  _M_buckets[__n] = __tmp;                      //               
  ++_M_num_elements;                            //      
  return iterator(__tmp, this);                 //      ,  
} insert_unique_noresize 와 insertequal_noresize 의 비교:
template 
void hashtable<_val>::clear()
{
  //       
  for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
    _Node* __cur = _M_buckets[__i];    //   
    while (__cur != 0) {               //       
      _Node* __next = __cur->_M_next;  //          
      _M_delete_node(__cur);           //          ,      
      __cur = __next;                  //    
    }
    _M_buckets[__i] = 0;               //        
  }
  _M_num_elements = 0;                 //       0   
} hashtable 복사
template 
void hashtable<_val>
  ::_M_copy_from(const hashtable& __ht)
{
  _M_buckets.clear();            //      
  _M_buckets.reserve(__ht._M_buckets.size());    //          ,           
  //                
  _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
  __STL_TRY {
    //   
    for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
      const _Node* __cur = __ht._M_buckets[__i];    //     (   )         
      if (__cur) {                                  //    
        _Node* __copy = _M_new_node(__cur->_M_val); //             
        _M_buckets[__i] = __copy;                   //               
        for (_Node* __next = __cur->_M_next;        //         ,   
             __next; 
             __cur = __next, __next = __cur->_M_next) {
          __copy->_M_next = _M_new_node(__next->_M_val); //      
          __copy = __copy->_M_next;                      //        
        }
      }
    }
    _M_num_elements = __ht._M_num_elements;              //        
  }
  __STL_UNWIND(clear());                                 //              
} 작은 매듭
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.