zoukankan      html  css  js  c++  java
  • hashtable

    参考《stl源码剖析》,用开链法实现了简易hash表,并进行了简单测试。

    特点:

    1. hash表可扩容。当元素个数大于hash表长的时候,hash表挑选下一个质数,扩容一倍。

    2. 提供了hash函数以及equal函数的载入

    3. 提供find,insert,erase三个基本操作。

        find返回某一元素的指针

        insert可选择不重复插入或可重复插入

        erase可选择删除一个元素或所有元素

    4. 省略了迭代器,静态数组未封装在类内

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 namespace ht {
      5     const  int _num_prime = 22;
      6     static const int prime_list[_num_prime] = {
      7         53,         97,           193,         389,       769,
      8         1543,       3079,         6151,        12289,     24593,
      9         49157,      98317,        196613,      393241,    786433,
     10         1572869,    3145739,      6291469,     12582917,  25165843,
     11         50331653,   100663319 
     12     };
     13 
     14     template<class Value>
     15     struct hashtable_node {
     16         Value val;
     17         hashtable_node *next;
     18         hashtable_node(Value val, hashtable_node *next):val(val), next(next){}
     19     };
     20     /*
     21     template<class Key>
     22     struct hashtable_iterator {
     23         typedef hashtable_node<Key> node;
     24         node *cur;
     25     };
     26     */
     27     template<class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
     28     struct hashtable{
     29         typedef hashtable_node<Key> node;
     30         
     31         Hash hash;
     32         KeyEqual equals;
     33         
     34         vector<node*> buckets;
     35         int num_elements;
     36 
     37         hashtable(int n = *prime_list){
     38             num_elements = 0;
     39             int n_buckets = next_size(n);
     40             buckets.resize(n_buckets);
     41         }
     42         ~hashtable(){
     43             for(auto cur: buckets) {
     44                 while(cur != NULL) {
     45                     node *tmp = cur->next;
     46                     delete cur;
     47                     cur = tmp;
     48                 }
     49             }
     50         }
     51 
     52         node* find(const Key& obj) {
     53             int n = hash(obj)%buckets.size();
     54             node *cur = buckets[n];
     55             while(cur) { 
     56                 if (equals(cur->val, obj)) 
     57                     return cur; 
     58                 cur = cur->next;
     59             }
     60             return cur;
     61         }    
     62         
     63         pair<node*, bool> insert(const Key& obj, bool same = false) {
     64             resize(num_elements + 1);
     65             const int n = hash(obj)%buckets.size();
     66             node *first = buckets[n], *tmp = NULL;
     67             if(same || (tmp = find(obj)) == NULL) {
     68                 tmp = new node(obj, first);
     69                 buckets[n] = tmp;
     70                 ++num_elements;
     71                 return {tmp, true};
     72             }
     73             return {tmp, false};
     74         }
     75 
     76         bool erase(const Key& obj, bool same = false) {
     77             if(find(obj) == NULL) return false;        
     78             int n = hash(obj)%buckets.size();
     79             node **cur = &buckets[n];
     80             while(*cur) {
     81                 if(equals((**cur).val, obj)) {
     82                     node *tmp = *cur;
     83                     *cur = tmp->next;
     84                     delete tmp;
     85                     --num_elements;
     86                     if(!same) break ;
     87                 }
     88                 else cur = &(**cur).next;
     89             }        
     90             return true;
     91         }
     92         
     93         void debug() {
     94             puts("debug...");
     95             bool tag = false;
     96             for(auto cur: buckets) {
     97                 tag = false;
     98                 while(cur) {
     99                     tag = true;
    100                     printf("%d ", cur->val);
    101                     cur = cur->next;
    102                 }
    103                 if(tag) puts("");
    104             }
    105             puts("end debug...");
    106         }
    107 
    108     private:
    109         int next_size(int n) {
    110             const int *last = prime_list+_num_prime;
    111             const int *pos = lower_bound(prime_list, last, n);
    112             return pos == last? *(last-1) : *pos;
    113         }
    114         void resize(int num) {
    115             int old_n = buckets.size();
    116             if(num > old_n){
    117                 int n = next_size(num);
    118                 if(n > old_n){
    119                     vector<node*> tmp(n, NULL);
    120                     for(int bucket = 0; bucket < old_n; ++bucket){
    121                         node *first = buckets[bucket];
    122                         while(first){
    123                             int new_bucket = hash(first->val)%n;
    124                             buckets[bucket] = first->next;
    125                             first->next = tmp[new_bucket];
    126                             tmp[new_bucket] = first;
    127                             first = buckets[bucket];
    128                         }
    129                     }
    130                     buckets.swap(tmp);
    131                 }
    132             }
    133         }
    134     };
    135 }
    136 
    137 int main() {
    138     ht::hashtable<int> H;
    139     
    140     H.insert(3);
    141     H.insert(3, true);
    142     H.insert(3, true);
    143     H.insert(3, true);
    144     H.insert(3);
    145     H.debug();
    146     printf("%d
    ", H.erase(3));
    147     H.debug();
    148 
    149     auto p = H.find(3);
    150     printf("%d
    ",p? p->val: (int)p);
    151     printf("%d
    ", H.erase(3, true));
    152 
    153     p = H.find(3);
    154     printf("%d
    ",p? p->val: (int)p); 
    155 
    156     H.insert(3);
    157     H.insert(3, true);
    158     H.insert(3, true);
    159     H.insert(3);
    160 
    161     H.insert(5);
    162     H.insert(5);
    163     H.debug();
    164     p = H.find(5);
    165     printf("%d
    ",p? p->val: (int)p);
    166 
    167     printf("%d
    ", H.erase(5));
    168     printf("%d
    ", H.erase(3));
    169     p = H.find(5);
    170     printf("%d
    ",p? p->val: (int)p);
    171     H.debug();
    172     return 0;
    173 }
  • 相关阅读:
    CSS3动画(性能篇)
    格拉西安《智慧书》中最有价值的23条法则
    HTML5系列四(特征检测、Modernizr.js的相关介绍)
    CSS3系列四(Media Queries移动设备样式)
    高性能JavaScript笔记三(编程实践)
    高性能JavaScript笔记二(算法和流程控制、快速响应用户界面、Ajax)
    LABjs(类似于LazyLoad,但它更加方便管理依赖关系)
    高性能JavaScript笔记一(加载和执行、数据访问、DOM编程)
    《代码大全》阅读笔记-34-软件工艺的话题
    《代码大全》阅读笔记-33-个人性格(personal character)
  • 原文地址:https://www.cnblogs.com/dirge/p/9607722.html
Copyright © 2011-2022 走看看