null8 查 找 8 查 找 二分查找及算法设计
二叉排序树及构造
平衡二叉树的查找、插入及旋转
hash表的构造及查找8.1 二分(折半)查找8.1 二分(折半)查找一、二分查找的先决条件
表中结点按关键字有序,且顺序(一维数组)存储。
二、二分法思想:取中,比较
(1)求有序表的中间位置mid
(2)若r[mid].key==k,查找成功;
若r[mid].key>k,在左子表中继续进行二
分查找;
若r[mid].key
r[m] : 在右半部分继续查找。 i=m+1=4,j=5m=(i+j)/2=4。r[m]==k :查找成功。m=(i+j)/2=6。null i=1,j=11, m=(i+j)/2=6。 r[m]k : 在左半部分继续查找。
i=7, j=m-1=8, m=(i+j)/2=7。 r[m]k : 在左半部分继续查找。
i=8, j=m-1=7 , i>j: 查找失败
1221303538404855566064二分法查找示例 (2)k=501 2 3 4 5 6 7 8 9 10 11 null三、存储结构
key info
typedef struct {
keytype key;
………….
} elemtype;
k1k2k3…………kn0
1
2
3
n
四、算法描述四、算法描述int Search_bin (elemtype r[], int n, keytype k) {
// r[1]..r[n] 是按key排序的n个元素,在表中查找 k
i=1 ; j=n ;
while ( i<=j ) {
mid=(i+j)/2 ; //取中
if (k== r[mid].key) return (mid) ; // 查找成功
else if (k< r[mid].key) j=mid-1; //在左半部分继续查找
else i=mid+1; //在右半部分继续查找
}
return(0);// k不在该有序表中。r[j].key题是: 如何选取 p ?
p 应为不大于m 的最大质数
例:设表长m=8,16,32,64,128,1001
则 p=7,13,31,61,127,1001四、冲突的概念与处理方法四、冲突的概念与处理方法 若对于不同的键值k1和k2,且k1 ≠ k2,
但 hash(k1)=hash(k2),即具有相同的散列地址,这种现象称为冲突。
称 k1、k2称为同义词。
例8.4 key={3,15,20,24},m=5(表长),
hash(k)=k%5
hash(15)=0
hash(20)=0 产生冲突。
冲突的处理——链地址法冲突的处理——链地址法将具有相同散列地址的记录都存储在同一个线性链表中。
例8.5
key={14,1,68,27,55,23,11,10,19,20,79,84},
hash(key)=key % 13, 用链地址法解决冲突,
构造hash表。
hash(14)=hash(1)=hash(27)=hash(79)=1
hash(68)=hash(55)=3
hash(19)=hash(84)=6
hash(20)=7
hash(23)=hash(10)=10
hash(11)=11
null127 79hash(key)=
key % 13
hash(14)=1
hash(1)=1
hash(68)=3
hash(27)=1
hash(55)=3
hash(23)=10
hash(11)=11
hash(10)=10
hash(19)=6
hash(20)=7
hash(79)=1
hash(84)=6146819 2023 11 55 84 10ASL=(6*1+4*2+1*3+1*4)/12=21/12冲突的处理——线性探测法冲突的处理——线性探测法 对给定的关键值 key,若地址d (即hash(key)=d)
的单元发生冲突,则依次探查下述地址单元:
d+1,d+2,….,m-1, 0 ,1,…d-1
直到找到一个开放的地址(空位置)止,将发生冲突的键值
放到该地址中。
设增量函数为d(i)=1,2,3,……m-1, m表长
i: 为探测次数。
null例8.6 以{14,1,68,27,55,23,11,10,19,20,79,84} , 构造
hash表。hash表长度为17, hash(key)=key % 17。
用线性探测法解决冲突。
hash 表: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 14681552720198479112310比较次数: 3 3
ASL=(1*10+3*2)/12=16/12