数据结构与算法总结(六)词典

词典结构:dict允许多个词条拥有相同的关键码。词条为关键码与值的合成结构。

映射结构:map要求不同词条的关键码互不相同。

例如跳转表:一种高效的词典结构,基于列表构造,时间复杂度为O(logn)。就是横层链表代表关键码,纵向列表代表值。一个关键码代表多个一样的值。

词典dict操作接口:GET(),PUT(),remove()..

跳转表:以QUADLIST为基础,有size(),LEBEL(),PUT,GET,REMOVE.
quadlist为四连表的含义。跳转表也就是一个链表代表层数,每一层也是一个链表为quadlist表。
QUADLIST表由quadlistNode节点构成。
quadlistNode节点:有前驱,后继,上邻和下邻四个方向。数据为词条=关键码和值的构成。
查找关键码K的操作:
        从顶层quadlist的首节点开始从前往后开始比较其关键码,
        if 不存在后继,则转入下一层
        if 存在后继且后继的关键码小于目标关键码,则转向下邻,下层前进。
        if 存在后继且后继的关键码大于目标关键码,则转向下邻,下层后退。

散列表:以最基本的向量为底层结构。通过适当的散列函数在关键码和向量单元的RANK之间建立映射关系。

散列函数构造:桶数组存放词条指针。桶数组容量,词条容量。
根据关键码可找到桶地址=散列函数。
沿关键码对应的桶地址查找链表,找到一致的关键码词条。

散列表、散列函数、冲突排解。

往往直接使用数组,此时的散列表成为桶数组。关键码空间到桶数组地址空间的映射函数为哈希函数.

hash(key)=rank; A[rank]=value;.根据KEY即可获得value。

散列函数的方法:除余法- key mod M。MAD法-a*key+b mod M。其中M为素数。伪随机数法。

冲突排解:多槽位法。每个桶安排多个槽位,可组织为向量或列表。缺点:利用率低。

独立连法:采用列表实现各子字典。缺点:需要遍历整个列表查找数据。

独立连法:关键码数范围为R,桶数为M,不同词条数为N。
R远大于M,M大于N。
散列函数:hash(key)=key % M,M通常为素数。key为整数。

开放定地址策略:线性试探法,平方试探法,再散列法等。发现通单元被占用则试探后一个通单元即可。

线性试探的查找策略:
1.当前桶单元命中目标关键码,则成功返回。
2.当前通单元非空,但关键码不等,则继续试探。
3.当前通单元为空,则查找失败。
在删除时会打断查找链,所以可设置一个标志位表示该桶尽管为空,但仍是查找链上一员。
确保装填因子小于0.5,增容量,转移词条,释放原桶数组。

散列码转换;关键码经过hashcode()成为散列码,经过hash()成为桶地址。

对于byte,short,int和char可表示为不超过32位整数的数据类型。可直接表示成散列码。

对于字符串来说;可用多项式散列码计算。

对long double类的解决办法为:将高32位和低32位分别看做两个32位整数,将二者之和作为散列码。
多项式散列码:
            h=0;n=s.length;
            for(i in n):
                h=h<<5;h+=(int)s[i];
                return h;

散列应用:桶排序,对于给定范围内的N个不同的数进行排序。遍历一遍即可。对于重复的情况即可使用链表即可。

桶排序主要是根据关键码进行排序:关键码可比较大小。

1.将关键码视作桶地址,将元素插入散列表中,即可顺序遍历散列表,输出非空桶中值即可得到排序结果。

2.最终都是要保证元素按照关键码的顺序放置在散列表中。每一个key都会映射一个地址,保证key的大小与地址大小一致。最后在遍历,即可排序。

猜你喜欢

转载自blog.csdn.net/u013070875/article/details/85639054