zoukankan      html  css  js  c++  java
  • 哈希表

     效率                        插入删除

    哈希表 O[1]
    树  O[N]
    链表   O[1]
    有序数组 O[N]

    缺点

    基于数组.难于扩展.被填满时候效率低下.无法有序遍历.

    哈希化:

    一种压缩方法把数位幂的连乘系统中得到的巨大的整数范围压缩到

    可接受的数组范围中。

    samllNumber = largetNumber%smallRange;

    这就是一种哈希函数:把一个大范围的数字哈希成一个小范围的数字.

    这个小的范围对应着数组的下标.

    arrayIndex = hugeNumber%arraySize;

    然后使用取余操作符.把得到的巨大的整数范围转换成两倍于要储存内容的数组下标范围:

    arraySize = numberWords*2;

    arrayIndex = hugeNumber%arraySize;

     

    哈希表:

    使用哈希函数向数组插入数据后.这个数组就称为哈希表.

    例子:

    想在内存中存储50000个单词.起初可能考虑每个单词占据一个数组单元.那么数组大小50000.

    同时可以使用数组下标存取单词.这样存取确实很快.

    单词转换成数组下标:

    *数字累加法

    一个转换单词的简单方法是把单词每一个字符代码求和.

    例如把单词cats转换成数字.

    c=3

    a=1

    t=20

    s=19

    然后把它们相加:3+1+20+19=43.那么在字典表中.单词cats存储在数组下标为43的

    单元中.所有的英文单词都用这个办法转换成数组下标.

    哈希函数.把一个大范围的数字数字哈希转化成一个小范围的数字.这个小范围的数字对应着数组的下标.

    arrayIndex = hugeNumber%arraySize;

    *幂连乘<----确保单词中的每个字符都可以通过独一无二的方法得到最终的数字.

    回忆一下:把单词每个字母乘以27的适当次幂.使单词成为一个巨大的数字.

     

    数字折叠:

    冲突:

    把巨大的数字空间压缩成较小的数字空间.必然要付出代价.不能保证每个单词映射到数组的空白单元.

    解决冲突:

    开放地址法:

    通过系统的方法找到数组的一个空位.把这个单词填入.

    而不再用哈西函数的到数组的下标.

     *线形探测:线性查找空白单元.

    find()
    //find item with key
    public DataItem find(int key){
    //assums table not full
    //hash the key
    int hashVal = hashFunc(key);
    //until empty cell
    while(hashArray[hashVal]!=null){
           if(hashArray[hashVal].getKey()==key)
                         return hashArray[hashVal];  
      
            ++hashVal;
    //wrap around if nessary hashVal
    %=arraySize; } return null; }
    //in this method i myself wanna insert a new item into the
    //assumes table not full
    public void insert(DataItem item)(
       //extract key
         int key = item.getKey();
      //hash the key
    //until empty cell or -1
         int hashVal = hashFunc(key);
    
    //find the propur index for the new item
         while(hashArray[hashVal]!=null &&
               hashArray[hashVal].iData!=-1
          ){
             ++hashVal;
             hashVal%=   arraySize;
           }
            hashArray[hashVal]=item;
    }       
    //delete dedecate  data item
    public DataItem delete(int key){
    //i got the dedecate data from the key
                   int hashVal =  
                hashFunc[key];
    //until the empty cell
    //found the key
            while(hashArray[hashVal]!=null){
                    if(hashArray[hashVal].getKey()==key){
                                   DateItem temp = //save item
                                      hashArray[hashVal];
                                 //leave it to empty cell
                                  hashArray[hashVal] = nonItem;
                                  return temp;
                    }
             ++hashVal;
             hashVal %= arrraySize;
           }
    }

     *二次探测

    在线形探测中.哈希函数原始下标 x.线形探测是x+1.x+2.x+3

    二次探测:x+1.x+4.x+9.x+16.x+25.

    当二次探测的搜索变长时候.好像它变得越来越绝望.第一次.它查找相邻的单元.

    如果这个单元被占用.它认为这里可能是一个小的聚集.所以它尝试距离为4的单元.

    如果这里也被占用.它变得焦虑.认为这里有一个更大的聚集.然后它尝试距离为9的单元.

    如果这里还被占用.它感到一丝恐慌.跳到距离为16的单元.很快它会歇斯底里的飞跃整个数组空间.

    当哈希表几乎填满时候.就会出现这种情况.

    二次探测的问题:

    二次探测消除了在线形探测中产生的聚集问题.这种聚集叫原始聚集.然而二次探测产生了另一种.更细的聚集问题.

    二次聚集.比如将184.302.420.544依次插入到表中.他们都影射到7.那么302需要以一为步长的探测.

    420需要以4为步长的探测.544需要以9为步长的探测.只要一有项.其关键字影射到7.就需要更长步长的探测.

    这种现象叫做二次聚集.

     *再哈希法

    stepSize = constant -(key%constant);
    constant是质数且小于数组容量
    stepSize = 5-(key%5);

    现在需要一种方法是产生一种依赖关键字的探测序列.而不是每个关键字都一样.

    对于指定的关键字.步长在整个探测中是不变的.不过不同的关键字使用不同的步长.

    表的容量是一个质数:

    再哈西法要求表的容量是一个质数.

    假设表的容量不是质数.例如假设表长是15<下标从0到14>

    有一个特定关键字映射到0.步长为5.探测序列是0.

    5 10 0 5 10 依次类推.一直循环.算法只尝试这三个单元.

    所以不能找到某些空白单元.

    例如位置1,2,3或者其他位置.算法会最终导致崩溃.

    链地址法:在哈西标的每个单元中设置链表  

    效率:

    查找/插入: 1+nComps -->nComps关键字比较次数

  • 相关阅读:
    raise PDFEncryptionError('Unknown algorithm: param=%r' % param) pdfminer.pdfdocument.PDFEncryptionError: Unknown algorithm
    Hive与Hbase的区别
    HIVE—索引、分区和分桶的区别
    MapReduce编程之Semi Join多种应用场景与使用
    MapReduce编程之Map Join多种应用场景与使用
    MapReduce编程之Reduce Join多种应用场景与使用
    Mapreduce——视频播放数据分类统计
    Docker-compose实战——Django+PostgreSQL
    Docker基础教程
    1.node接口搭建--express搭建服务器
  • 原文地址:https://www.cnblogs.com/cici-new/p/3990629.html
Copyright © 2011-2022 走看看