-
查找表:由同一类型的数据元素(或记录)构成的集合
-
查找表的种类:
- 静态查找表:仅作查询操作的查找表
- 动态查找表:在查找的过程中同时插入表中不存在的元素,或从表中删除已存在的元素。
-
ASL:平均查找长度,用以衡量查找算法。
ASL定义为确定记录在表中的位置时进行的比较次数的平均值:ASL= ∑ i = 1 n p i c i \sum_{i=1}^{n}p_ic_i ∑i=1npici。
- n n n 为查找表的长度;
- p i p_i pi 为查找第 i i i个元素的概率
- c i c_i ci 为查找第 i i i个元素时与给定值进行比较的次数。
一、顺序查找
- 从表中最后一个记录开始
- 以待查找元素作为序列的第0个元素
- 从后往前逐个比较关键字,在关键字相等时返回
- 若返回的位置为0,则查找失败
二、二叉排序树
二叉排序树为动态查找表。 其具有以下性质:
- 若它的左子树不空,则左子树上所有节点的值都小于根节点的值;
- 若它的右子树不空,则右子树上所有节点的值都大于根节点的值;
- 它的左、右子树也分别为二叉排序树。
对二叉排序树进行中序遍历可以得到一个有序序列。
插入
- 比对需插入的值 temp 与根节点的值;
- 若大于根节点的值,且根节点的右子树为空,则插入至根节点的右子树;若右子树非空,则取根节点为右子树,继续判断;
- 若小于根节点的值,且根节点的左子树为空,则插入至根节点的左子树;若左子树非空,则取根节点为左子树,继续判断;
删除
被删除节点具有以下三种情况:
- 叶子节点:
直接将该节点删除即可。 - 只有左子树或右子树:
删除节点,用其孩子节点代替被删除节点即可。 - 同时有左右子树:
以中序遍历的直接前驱代替待删除结点,然后再删除直接前驱原位置的结点。该直接前驱只可能有左孩子。
三、哈希表
哈希表又称散列表,是一种计算记录存放地址的方法,其在关键码与存储位置之间直接建立了映像。
哈希函数
哈希函数在记录的关键字与记录的存储地址之间建立起一种对应,可写成:
- 其中 H ( ⋅ ) H(·) H(⋅)为哈希函数
- k e y i key_i keyi时表中元素 a i a_i ai的关键字, a d d r ( a i ) addr(a_i) addr(ai)为存储地址
即哈希函数对关键字进行运算,得到存储地址。
哈希查找
- 首先利用哈希函数即记录的关键字计算出记录的存储地址;
- 然后直接找到指定的记录;
- 无需经过比较,通过一次存取就能得到所查元素。
处理冲突
为产生冲突的地址寻找下一个哈希地址。处理冲突主要有三种方法:
- 开放定址法
- 再哈希法
- 链地址法
开放定址法
为产生冲突的地址 H ( k e y ) H(key) H(key)求得一个地址序列: H 0 , H 1 , H 2 , … , H s H_0,H_1,H_2,…,H_s H0,H1,H2,…,Hs,然后再进行运算:
其中, H ( k e y ) H(key) H(key)为哈希函数, m m m为哈希表长。
-
线性再探测
当 d i d_i di取 1 , 2 , 3 , … , m − 1 1,2,3,…,m-1 1,2,3,…,m−1时,称这种开放定址法为线性探测再散列。 -
二次探测
当 d i d_i di取 1 2 , − 1 2 , 2 2 , − 2 2 , 3 2 , … 1^2,-1^2,2^2,-2^2,3^2,… 12,−12,22,−22,32,…时,称这种开放定址法为二次探测再散列。
优点:只要哈希表中有空位置,总能找到一个不发生冲突的地址;
缺点:易产生“二次聚集”,即再处理同义词的冲突过程中,又产生非同义词的冲突,对查找不利。