zoukankan      html  css  js  c++  java
  • 《数据结构》C++代码 散列表

           散列表,又名哈希表、Hash表。这是一个神奇的数据结构,它的复杂度是常数级别,由于我非常喜欢这个数据结构,在此简单介绍一下。

           (没有学过Hash表的同学,我推荐一个教程:http://www.cnblogs.com/jiewei915/archive/2010/08/09/1796042.html

           让我们回忆一下之前学过的数据结构,列个表,与Hash表做个比较(表中c表示常数):

     

    插入时间

    删除时间

    查找时间

    编程复杂度

    信息剖析度

    无序数组

    1

    N

    N

    有序数组

    N

    N

    logN

    无序链表

    1

    N

    N

    ☆☆☆

    平衡树

    logN

    logN

    logN

    ☆☆☆☆☆

    Hash表

    常数

    常数

    常数

    ☆☆

    ☆☆☆

           这表中前四列很好理解(平衡树之所以给五颗星,是因为我假设大家树写得好看,如果代码不漂亮,恐怕多少颗星都有可能,甚至你写不对就是∞颗星……),而第五列新手可能比较陌生,这里解释一下。

           例如你对N个元素写个无序结构,啥都不用想,存进去就好了;写个有序结构,也仅仅需要想想两个元素之间如何比大小即可(例如3<5、"ab"<"aca"),我们对这N个数本身的信息剖析得非常少。因此,像这种信息剖析度低的数据结构,你基本啥都不用想,拿来就可以写代码了。

           但Hash表却并不是如此,我们需要对数据进行更深入的分析(例如数是不是整数、字符串有多长),否则你的Hash表就可能出错(例如有负数时,你直接去模)、复杂度退化为线性等等(例如很多数都是一个大素数K的整数倍,而你却正好选择了让每个数模K去Hash)。因此,养成分析数据的习惯,才能知道自己在具体题目中是否可以使用散列表、如何使用散列表。

           好了,就介绍这么多。最后,既然我说Hash表的编程复杂度只有两颗星,那么下面给出我的代码(Hash表有很多种,我最常用的就是大素数Hash+链表存重,代码简单而且适用性强):

    题目:sjtuoj 1224

    清爽版:Hash表的代码,清爽版对于新手来说很容易搞乱,因此仅给出类版。

    类版:

    1、裸Hash表(本题内存足够大,所以能过)

    2、模大素数+拉链(对于本题来说,比较NC的做法,感谢HQ同学提示可以直接采用裸Hash表AC)

     1 #include <cstring>
     2 
     3 // 裸Hash 类版
     4 class Hash
     5 {
     6     int H[4000000];
     7     int k(int num) { return num+2000000; }
     8     int num(int k) { return k-2000000; }
     9 public:
    10     Hash() { memset(H,0,sizeof(H)); } // 此代码中,由于这个Hash表比较大,会定义在全局,故无需初始化
    11     void in(int num) { ++H[k(num)]; }
    12     int count(int num) { return H[k(num)]; }
    13 };
    14 
    15 // 模大素数+拉链表 类版
    16 class Hash
    17 {
    18     struct hash
    19     {
    20         int num;
    21         hash *next;
    22     }*H[250000],New[250000];
    23     int L;
    24     hash* make(int num) { New[L].num=num; return New+L++; }
    25     int k(int num) { return (num+2000000)%249989; }
    26 public:
    27     Hash():L(0) { memset(H,0,sizeof(H)); } // 此代码中,由于这个Hash表比较大,会定义在全局,故无需初始化
    28     void in(int num)
    29     {
    30         hash *u=make(num);
    31         u->next=H[k(num)]; H[k(num)]=u;
    32     }
    33     int count(int num)
    34     {
    35         int s=0;
    36         for(hash *u=H[k(num)];u;u=u->next)
    37             if(u->num==num) ++s;
    38         return s;
    39     }
    40 };
  • 相关阅读:
    deep_learning_Function_tensorflow_reshape()
    deep_learning_tensorflow_get_variable()
    deep_learning_Function_tensorflow_random_normal_initializer
    deep_learning_Function_numpy_newaxis参数
    deep_learning_Function_tensorflow_unpack()
    deep_learning_Function_tensorflow_transpose()
    deep_learning_LSTM长短期记忆神经网络处理Mnist数据集
    deep_learning_Function_rnn_cell.BasicLSTMCell
    嵌入式技术基础与实践-学习札记(一)
    2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组
  • 原文地址:https://www.cnblogs.com/icedream61/p/4141946.html
Copyright © 2011-2022 走看看