算法导论笔记——第十~十一章 数据结构(一) 散列

第十章 基本数据结构

栈:可由数组表示

队列:可由数组表示

指针和对象:可由多数组表示。可用栈表示free list

有根数:

  二叉树:左右孩子

  分支无限制:左孩子右兄弟表示法

 

第十一章 散列表

数组:为每个元素保留一个位置

散列表:用于实际存储关键字比全部可能关键字少很多时,比如字典操作

解决散列冲突:链接法,开放寻址法

11.2 散列表

用链表法,在简单均匀散列的假设下,一次成功或不成功的查找所需要的平均时间为Θ(1+α),α为load factor。

11.3 散列函数

好的散列函数应(近似地)满足简单均匀假设:每个关键字都被等肯能地散列到m个槽位中的任何一个,并与其它关键字已散列到哪个槽位无关。

  利用关键字分布的有用信息。如“pt”,“pts”不冲突

  一种好的方法导出的散列值,在某种程度上应独立于数据可能存在的任何模式。如除法散列

  散列函数的某些应用可能会要求比简单均匀散列更强的性质,如全域散列可使相似关键字有截然不同散列值。

全域散列函数:一组函数H称为全域的,如果对每一对不同的关键字k,l属于U,满足h(k)=h(l)的散列函数个数至多为[H]/m,m为槽位数。

  如:p为足够大素数,使得每一关键字k都在[0,p-1],Zp={0,1,...,p-1},Zp*={1,2,...,p-1},

    hab(k)=((ak+b)mod p)mod m

    Hpm={hab: a属于Zp*,b属于Zp}

   11.4 开放寻址法

  所有元素都在散列表中,装载因子不超过1。探查顺序是0~m-1的一个排列,依赖于h(k,i),i为探查号。不使用指针,节省空间。

  但有关键字删除时即使设置标志deleted,查找时间也不再依赖于a。这种情况更适合用链接法来解决冲突。

  均匀散列:每个关键字的探查序列等可能地为0~m-1的m!种排列的任一种。难实现,只能近似(如双重散列)。

  三种技术:线性探查,二次探查,双重探查。

  线性探查:h(k,i)=(h'(k)+i)mod m。连续被占用时间越多,查找时间越长。

  二次探查:h(k,i)=(h'(k)+c1i+c2i2)mod m。初始位置决定探查序列。

  双重探查:h(k,i)=(h1(k)+ih2(k))mod m。

  11.5 完全散列

  散列有良好的平均性能。

  特别地,当关键值是静态(存入后不变,如程序的保留字)时,完全散列能提供出色的最坏情况性能O(1)。

  通过两级的散列来设计完全散列方案,在每级上都使用全域散列。二次散列表不用链表,通过精心选择hi,确保在第二级上不发生冲突。

  定理11.9: 如果从一个全域散列函数类中随机算出散列函数h,将n个关键字存储在一个大小为m=n2的散列表中,那么表中出现冲突的概率小于1/2.

  定理11.10: 如果从一个全域散列函数类中随机算出散列函数h,用它将n个关键字存储在一个大小为m=n的散列表中,则有

    E[Σnj2]<2n  nj为散列到槽j的关键值数。

  推论:如果二次散列大小为mj=nj2,则存储所有二次散列表所需的存储总量的期望值小于2n。

  推论2:存储所有二次散列表的存储总量等于或大于4n的概率小于1/2。

posted on 2017-08-16 18:31  胖子一刚  阅读(368)  评论(0编辑  收藏  举报

导航