精华内容
下载资源
问答
  • 拉链法

    千次阅读 2018-05-24 16:41:51
    一、有序集合求交集的方法有 a)二重for循环法,时间复杂度O(n*n) b)拉链法,时间复杂度O(n) c)水平分桶,多线程并行 d)bitmap,大大提高运算并行度,时间复杂度O(n) e)跳表,时间复杂度为O(log(n))以下是...

    list1与list2求交集的方法总结!

    一、有序集合求交集的方法有

             a)二重for循环法,时间复杂度O(n*n)

             b)拉链法,时间复杂度O(n)

             c)水平分桶,多线程并行

             d)bitmap,大大提高运算并行度,时间复杂度O(n)

             e)跳表,时间复杂度为O(log(n))

    以下是方法的具体介绍:

    方案一:for * for,土办法,时间复杂度O(n*n)

        每个搜索词命中的网页是很多的,O(n*n)的复杂度是明显不能接受的。倒排索引是在创建之初可以进行排序预处理,问题转化成两个有序的list求交集,就方便多了。

    方案二:有序list求交集,拉链法

        

          有序集合1{1,3,5,7,8,9}

          有序集合2{2,3,4,5,6,7}

        两个指针指向首元素,比较元素的大小:

        (1)如果相同,放入结果集,随意移动一个指针

        (2)否则,移动值较小的一个指针,直到队尾

      这种方法的好处是:

      (1)集合中的元素最多被比较一次,时间复杂度为O(n)

      (2)多个有序集合可以同时进行,这适用于多个分词的item求url_id交集

      这个方法就像一条拉链的两边齿轮,一一比对就像拉链,故称为拉链法

    方案三:分桶并行优化

        数据量大时,url_id分桶水平切分+并行运算是一种常见的优化方法,如果能将list1<url_id>和list2<url_id>分成若干个桶区间,每个区间利用多线程并行求交集,各个线程结果集的并集,作为最终的结果集,能够大大的减少执行时间。

         举例:

          有序集合1{1,3,5,7,8,9, 10,30,50,70,80,90}

          有序集合2{2,3,4,5,6,7, 20,30,40,50,60,70}

         求交集,先进行分桶拆分:

          桶1的范围为[1, 9]

          桶2的范围为[10, 100]

          桶3的范围为[101, max_int]

        于是:

        集合1就拆分成

        集合a{1,3,5,7,8,9}

        集合b{10,30,50,70,80,90}

        集合c{} 

        集合2就拆分成

        集合d{2,3,4,5,6,7}

        集合e{20,30,40,50,60,70}

        集合e{}

        每个桶内的数据量大大降低了,并且每个桶内没有重复元素,可以利用多线程并行计算:

        桶1内的集合a和集合d的交集是x{3,5,7}

        桶2内的集合b和集合e的交集是y{30, 50, 70}

        桶3内的集合c和集合d的交集是z{}

        最终,集合1和集合2的交集,是x与y与z的并集,即集合{3,5,7,30,50,70}

    方案四:bitmap再次优化

        数据进行了水平分桶拆分之后,每个桶内的数据一定处于一个范围之内,如果集合符合这个特点,就可以使用bitmap来表示集合:

          

     

      如上图,假设set1{1,3,5,7,8,9}和set2{2,3,4,5,6,7}的所有元素都在桶值[1, 16]的范围之内,可以用16个bit来描述这两个集合,原集合中的元素x,在这个16bitmap中的第x个bit为1,此时两个bitmap求交集,只需要将两个bitmap进行“与”操作,结果集bitmap的3,5,7位是1,表明原集合的交集为{3,5,7}

         水平分桶,bitmap优化之后,能极大提高求交集的效率,但时间复杂度仍旧是O(n)

        但bitmap需要大量连续空间,占用内存较大

    方案五:跳表skiplist

        有序链表集合求交集,跳表是最常用的数据结构,它可以将有序集合求交集的复杂度由O(n)降至O(log(n))

         

        集合1{1,2,3,4,20,21,22,23,50,60,70}

        集合2{50,70}

        要求交集,如果用拉链法,会发现1,2,3,4,20,21,22,23都要被无效遍历一次,每个元素都要被比对,时间复杂度为O(n),能不能每次比对“跳过一些元素”呢?

    跳表就出现了:

          

        集合1{1,2,3,4,20,21,22,23,50,60,70}建立跳表时,一级只有{1,20,50}三个元素,二级与普通链表相同,集合2{50,70}由于元素较少,只建立了一级普通链表;如此这般,在实施“拉链”求交集的过程中,set1的指针能够由1跳到20再跳到50,中间能够跳过很多元素,无需进行一一比对,跳表求交集的时间复杂度近似O(log(n)),这是搜索引擎中常见的算法。

     

     

     

    本片博客转载自以下网站(本着分享以及保存以便日后复习的目的发布此博客):

    展开全文
  • 易语言源码易语言拉链法哈希表源码.rar 易语言源码易语言拉链法哈希表源码.rar 易语言源码易语言拉链法哈希表源码.rar 易语言源码易语言拉链法哈希表源码.rar 易语言源码易语言拉链法哈希表源码.rar 易语言源码...
  • 一个关键字会映射到同一个位桶中的情况,这种情况就就叫做哈希冲突,解决哈希冲突的有三种方案,一种叫做拉链法(也叫作链接法、链地址法,一个意思),另外三种分别为开发地址法和再散列法。 一、拉链法 ...

    上篇博客我们说到了,什么是哈希冲突,其实就是再采用哈希函数对输入域进行映射到哈希表的时候,因为哈希表的位桶的数目远小于输入域的关键字的个数,所以,对于输入域的关键字来说,很可能会产生这样一种情况,也就是,一个关键字会映射到同一个位桶中的情况,这种情况就就叫做哈希冲突,解决哈希冲突的有三种方案,一种叫做拉链法(也叫作链接法、链地址法,一个意思),另外三种分别为开发地址法和再散列法。

    一、拉链法

    上篇博文我们举的例子,HashMap,HashSet其实都是采用的拉链法来解决哈希冲突的,就是在每个位桶实现的时候,我们采用链表(jdk1.8之后采用链表+红黑树)的数据结构来去存取发生哈希冲突的输入域的关键字(也就是被哈希函数映射到同一个位桶上的关键字)。首先来看使用拉链法解决哈希冲突的几个操作:

    ①插入操作:在发生哈希冲突的时候,我们输入域的关键字去映射到位桶(实际上是实现位桶的这个数据结构,链表或者红黑树)中去的时候,我们先检查带插入元素x是否出现在表中,很明显,这个查找所用的次数不会超过装载因子(n/m:n为输入域的关键字个数,m为位桶的数目),它是个常数,所以插入操作的最坏时间复杂度为O(1)的。

    ②查询操作:和①一样,在发生哈希冲突的时候,我们去检索的时间复杂度不会超过装载因子,也就是检索数据的时间复杂度也是O(1)的

    ③删除操作:如果在拉链法中我们想要使用链表这种数据结构来实现位桶,那么这个链表一定是双向链表,因为在删除一个元素x的时候,需要更改x的前驱元素的next指针的属性,把x从链表中删除。这个操作的时间复杂度也是O(1)的。

     

    拉链法的优点

    与开放定址法相比,拉链法有如下几个优点:

    ①拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;

    ②由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;

    ③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;

    ④在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。

     

    拉链法的缺点

    指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。

    使用例子:

    HashMap

    二、开发地址法

    开放地址法有个非常关键的特征,就是所有输入的元素全部存放在哈希表里,也就是说,位桶的实现是不需要任何的链表来实现的,换句话说,也就是这个哈希表的装载因子不会超过1。它的实现是在插入一个元素的时候,先通过哈希函数进行判断,若是发生哈希冲突,就以当前地址为基准,根据再寻址的方法(探查序列),去寻找下一个地址,若发生冲突再去寻找,直至找到一个为空的地址为止。所以这种方法又称为再散列法。

    有几种常用的探查序列的方法:

    ①线性探查

    dii=1,2,3,…,m-1;这种方法的特点是:冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。

    (使用例子:ThreadLocal里面的ThreadLocalMap)

    ②二次探查

    di=12,-12,22,-22,…,k2,-k2    ( k<=m/2 );这种方法的特点是:冲突发生时,在表的左右进行跳跃式探测,比较灵活。

    ③ 伪随机探测

    di=伪随机数序列;具体实现时,应建立一个伪随机数发生器,(如i=(i+p) % m),生成一个位随机序列,并给定一个随机数做起点,每次去加上这个伪随机数++就可以了。

    三、再哈希法

    再哈希法其实很简单,就是再使用哈希函数去散列一个输入的时候,输出是同一个位置就再次哈希,直至不发生冲突位置

    缺点:每次冲突都要重新哈希,计算时间增加。

    展开全文
  • 易语言拉链法哈希表源码
  • HashMap拉链法简介

    千次阅读 2020-05-20 10:28:49
    拉链法用途 解决hash冲突(即put操作时计算key值问题)。 拉链法原理 把具有相同散列地址的关键字(同义词)值放在同一个单链表中,称为同义词链表。 有m个散列地址就有m个链表,同时用指针数组A[0,1,2…m-1]存放各个...

    拉链法用途
    解决hash冲突(即put操作时计算key值问题)。

    拉链法原理
    把具有相同散列地址的关键字(同义词)值放在同一个单链表中,称为同义词链表
    有m个散列地址就有m个链表,同时用指针数组A[0,1,2…m-1]存放各个链表的头指针,凡是散列地址为i的记录都以结点方式插入到以A[i]为指针的单链表中。A中各分量的初值为空指针。

    拉链法原理解释
    HashMap是一个数组,数组中的每个元素是链表。put元素进去的时候,会通过计算key的hash值来获取到一个index,根据index找到数组中的位置,进行元素插入。当新来的元素映射到冲突的数组位置时,就会插入到链表的头部。

    HashMap采用拉链法将HashMap的key是转化成了hashcode,但hashcode可能重复,所以采用求交集方式解决冲突
    在这里插入图片描述
    举例如下
    有序集合a1={1,3,5,7,8,9},有序集合a2={2,3,4,5,6,7}
    两个指针指向首元素,比较元素的大小:
    (1)如果相同,放入结果集,随意移动一个指针
    (2)否则,移动值较小的一个指针,直到队尾
    好处:
    (1)集合中的元素最多被比较一次,时间复杂度为O(n)。
    (2)多个有序集合可以同时进行,这适用于多个分词的item求url_id交集。
    这个方法就像一条拉链的两边齿轮,然后逐个对比,故称为拉链法

    展开全文
  • 拉链法1.2.查询1.2.1.开放寻址法1.2.3.拉链法 哈希 mod的数一般取一个质数 离2的整数次幂尽量远 大于10万的第一个质数,1e5+3; 1.原子操作 1.1.插入 1.1.1.开放寻址法 h[find(x)]=x; 1.1.2.拉链法 void insert(int ...

    哈希

    mod的数一般取一个质数

    离2的整数次幂尽量远

    大于10万的第一个质数,1e5+3;

    1.原子操作

    1.1.插入

    1.1.1.开放寻址法

    h[find(x)]=x;
    

    1.1.2.拉链法

    void insert(int x)
    {
      int k=(x%N+N)%N;
      e[idx]=x;
      ne[idx]=h[k];
      h[k]=idx++;
    }
    

    1.2.查询

    1.2.1.开放寻址法

    void find(int x){
      int t = (x%N+N)%N;
      
      while(h[t]!=null&&h[t]!=x)
      {
        t++;
        if(t==N) t=0;
      }
      return t;
    }
    

    1.2.3.拉链法

    bool find(int x)
    {
      int k = (x%N+N)%N;
      for(int i=h[k];i!=-1;i=ne[i])
        if(e[i]==x)
          return true;
      return false;
    }
    

    2.字符串哈希

    P一般取131

    首先核心在于,将一段字符串映射为一个数

    abcde注意字符串是从左往右看的,但是从右往左依次是高位。

    那么求de这个字符串表示时候,l=4,r=5

    h [ r ] = h [ 5 ] h[r]=h[5] h[r]=h[5],代表 a b c d e abcde abcde代表 a ∗ q 5 + b ∗ q 4 + c ∗ q 3 + d ∗ q 2 + e ∗ q 1 a*q^5+b*q^4+c*q^3+d*q^2+e*q^1 aq5+bq4+cq3+dq2+eq1

    h [ l − 1 ] = h [ 3 ] h[l-1]=h[3] h[l1]=h[3]代表 a b c abc abc代表 a ∗ q 3 + b ∗ q 2 + c ∗ q 1 a*q^3+b*q^2+c*q^1 aq3+bq2+cq1

    下面是一个小技巧,使用ULL,相当于队 2 64 2^{64} 264取模

    ULL get(int l,int r)
    {
      return h[r]-h[l-1]*q[r-l+1];
    }
    
    ULL h[N],p[N];
    
    int main(){
      scanf("%d%d",&n,&m);
      scanf("%s",str+1);
      p[0]=1;
      
      for(int i=1;i<=n;i++);
      {
        h[i]=h[i-1]*P+str[i];
        p[i]=p[i-1]*P;
      }
      while(m--)
      {
        int l1,r1,l2,r2;
        scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
        if(get(l1,r1)==get(l2,r2)) puts("Yes");
        else puts("No");
      }
      return 0;
    }
    
    展开全文
  • l拉链法

    2018-10-10 20:28:06
    //拉链法(利用链表)解决哈希冲突问题 #include &lt;iostream&gt; #include &lt;ctime&gt; #define INDEXBOX 7 //哈希表的元素个数 #define MAXNUM 13 //数据个数 using...
  • 字典也叫散列表,最大的特点是通过key来查找其对应的值其时间复杂度是O(1),下面这篇文章就来给大家介绍介绍python利用拉链法实现字典的方法。 在Python中怎样用列表实现字典? 用列表实现字典最大的问题就是解决hash...
  • 哈希拉链法

    2018-10-16 17:19:28
    哈希拉链法 前言 前面学习到的几种算法比如 红黑树 , 二叉搜索树 ,查找插入 时间复杂度 最快也只能到 O(logn) .现在介绍一种算法可以使查找插入 时间复杂度 达到常数级别。 散列表(Hash table) 也...
  • 哈希——拉链法

    千次阅读 2018-03-01 15:25:06
    首先写哈希——拉链法要知道哈希冲突。 哈希冲突: 对于两个数据元素的关键字 Ki 和 Kj (i != j),有 Ki != J ,但有: HashFun(Ki) == HashFun(Kj) 即不同关键字通过相同哈希哈数计算出相同的哈希地址,该种...
  • php hash 拉链法

    2017-05-27 11:33:14
    php 模拟hash 拉链法 :)<?php /** * FILE_NAME:hash.php * AUTHOR: ChenShuai * Date: 2017/5/27 * DESC: */class myhash{ public $bucket = []; /** * @param $key * @return int * @a
  • 数据结构——拉链法(链地址法)

    千次阅读 2019-12-10 20:54:16
    当存储结构是链表时,多采用拉链法,用拉链法处理冲突的办法是:把具有相同散列地址的关键字(同义词)值放在同一个单链表中,称为同义词链表。有m个散列地址就有m个链表,同时用指针数组T[0..m-1]存放各个链表的头...
  • 拉链法哈希表

    2019-07-03 10:52:00
    拉链法哈希表 2019-07-03 13:31:32 import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.Iterator; /** * @ClassName SeparateChainHashST * @Author wangyudi * @Date...
  • 开放寻址法和拉链法十分类似,只是处理冲突的方式不一样。拉链法通过在冲突位置开链表解决,开放寻址法通过往后顺次找空位置解决。 拉链法: #include<iostream> #include<cstdio> #include<vector&...
  • 拉链法的理解

    2019-09-23 19:15:18
    原理 把具有相同散列地址的关键字(同义词)值放在同一个单链表中,称为同义词链表。有m个散列地址就有m个链表,同时用指针数组T[0..m-1]存放各个链表的头指针,...HashMap就用了拉链法 HashMap的key是转化成了hash...
  • 什么是拉链法

    万次阅读 2018-07-02 20:09:04
     拉链法又叫链地址法,Java中的HashMap在存储数据的时候就是用的拉链法来实现的,拉链发就是把具有相同散列地址的关键字(同义词)值放在同一个单链表中,称为同义词链表。有m个散列地址就有m个链表,同时用指针数组T...
  • 开放地址法和拉链法分别是怎么解决哈希冲突的,希望可以通俗一点,感谢大咖们的帮助
  • 用java写的拉链法实现哈希表的建立,应用到类似于电话本查询的程序里,课程设计时候做的,所以不是很完美
  • 拉链法实现字典

    2017-03-24 20:30:00
    字典: 也叫散列表,最大的特点是通过key来查找其对应的值其时间复杂度是O(1). 在Python中怎样用列表实现字典...拉链法:就是在一个列表中每个位置再添加一个列表,这样就算是有hash冲突也能够存储进去,当选取的has...
  • hash表拉链法解决冲突

    2019-08-07 17:20:47
    拉链法 Java 标准库的 HashMap 基本上就是用 拉链法 实现的。 拉链法 的实现比较简单,将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。 ...
  • 哈希表的拉链法

    2021-01-11 19:37:44
    拉链法 Hash(KEY) = Positon; 在Postion下面形成一个单链表,存储所有以该Positon为存储地址的数据。 找一个比数据范围略大的大质数 例如数据范围是10W for(int i = 100000; ; i++) { bool bFlag = true; ...
  • 拉链法(链地址法)

    万次阅读 多人点赞 2016-03-24 10:25:53
    当存储结构是链表时,多采用拉链法,用拉链法处理冲突的办法是:把具有相同散列地址的关键字(同义词)值放在同一个单链表中,称为同义词链表。有m个散列地址就有m个链表,同时用指针数组T[0..m-1]存放各个链表的头...
  • 哈希表(拉链法)

    2020-01-04 16:02:31
    文章目录哈希表(拉链法)单链表的插入操作单链表练习 哈希表(拉链法) #include <stdio.h> #include <vector> struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {...
  • (1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短; (2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况; (3)开放定址法为减少冲突...
  • 拉链法: 用数组h[N]来表示拉链法上对应的链,如果遇到冲突则在对应冲突的位置开一个链,创建链的方式和之前单链表的方式相同。如果要插入一个值: 计算当前值在哈希之后的映射位置int k = (x % N + N) % N;之所以...
  • 散列表线性探测法外拉链法 #include &amp;amp;lt;iostream&amp;amp;gt; #include &amp;amp;lt;algorithm&amp;amp;gt; using namespace std; struct Node { int key; Node *next; }; Node ...
  • 哈希冲突之拉链法

    千次阅读 2015-09-10 19:56:17
    解决哈希冲突一种比较直接的办法就是,将大小为M的数组的每一个元素指向一条链表,链表中的每一个节点都存储一个哈希值为该索引的键,这就是拉链法。 该方法的基本思想就是选择足够大的M,使得所有的链表都尽可能短...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,255
精华内容 6,502
关键字:

拉链法