所用教材:
书名:《数据结构–用C语言描述(第2版)》
编者:耿国华;张德同;周明全等编著
出版社:高等教育出版社
P315页
2.编写一个函数,利用折半查找算法在一个有序表中插入一个元素x,并保持表的有序性。
#include<stdio.h>
#define Max 50
//有序表中数据类型
typedef int KeyType;
//有序表
typedef struct{
KeyType elem[Max];
int length;
}RecordList;
//折半查找并插入算法
int BinSrch(RecordList *l,KeyType k){
int i; //查找
int low=1,high=l->length;
int mid;
while(low<=high){
mid=(low+high)/2;
if(k==l->elem[mid]) return(mid);
else if (k<l->elem[mid]) high=mid-1;
else low=mid+1;
}//while
for(i=l->length;i>=low;i--){ //插入
l->elem[i+1]=l->elem[i];
}//for
l->elem[low]=k;
l->length++;
}
//主函数
int main(){
RecordList L;
int i;
KeyType x;
L.elem[0]=0; //第一个数组元素不作使用
printf("请输入原始有序表查长度:");
scanf("%d",&(L.length));
for(i=1;i<=L.length;i++){
printf("请输入有序表第%d个数据:",i);
scanf("%d",&(L.elem[i]));
getchar();
}
printf("所插入的数据为:");
scanf("%d",&x);
BinSrch(&L,x);
printf("插入数据所得有序表为:");
for(i=1;i<=L.length;i++){
printf("%d ",L.elem[i]);
}
}
12.选取哈希函数H(k)=(3k)%11,用线性探测再散列法处理冲突。试在0-10的散列地址空间中,对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,并求等概率情况下查找成功与不成功时的平均查找长度。
上课只讲了查找成功平均查找长度:
通过查询了解了查找不成功平均查找长度
通过以下题目进行解释:
选取哈希函数H(k)=(3k)%11,用线性探测再散列法处理冲突。试在0-10的散列地址空间中,对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,并求等概率情况下查找成功与不成功时的平均查找长度。
22: (22X3)%11=0
41: (41X3)%11=2
53: (53X3)%11=5
46: (46X3)%11=6
30: (30X3)%11=2
(2+1)%11=3
13: (13X3)%11=6
(6+1)%11=7
01: (01X3)%11=3
(3+1)%11=4
67: (67X3)%11=3
(3+1)%11=4
(3+2)%11=5
(3+3)%11=6
(3+4)%11=7
(3+5)%11=8
则得到:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
22 | 41 | 30 | 01 | 53 | 46 | 13 | 67 |
ASLsucc=(1+1+1+1+2+2+2+6)/8=2
ASLsucc=查找次数总合/元素个数
ASLunsucc=(2+1+8+7+6+5+4+3+2+1+1)/11=40/11
解释一下这里:
假设有一个数,哎,取余之后等于0,应该放到0号地址里,但是里面有22了,那会怎么办呢,用线性探测散列(题目要求),(0+1)%11=1,这样放到1号地址就可以了。一共运算了2次才找到合适的位置。这就是第一个2的由来。
1的由来就是假设有一个数第一次取余之后为1,1号位置为空,正好可以放到里面。一共运算了1次才找到合适的位置。
8的由来就是假设一个数第一次取余之后为2,2号有数了,那么线性探测散列,(2+1)%11=3,但3号地址也有数了,那么(2+2)%11=4,但4号位置也有数了,继续线性探测散列,直到(2+7)%11=9,放到了9号位置里面。这样一共需要运算8次才找到。
后面的类推。
也就是说:当给某个数,它第一次取余之后的可能性为0-10,这不要紧,算出来每种情况下需要进行几次运算才能放到表里面就行,然后把所有运算次数相加,除以表的长度。
注意:
当发生冲突使用线性探测散列时,不需要再乘以系数,对于本题来说也就是不用再乘3了。