判断题:
1、把数组中元素按某种顺序排列的过程叫做查找 。
F 把数组中元素按某种顺序排列的过程叫做排序。
2、将N个数据按照从小到大顺序组织存放在一个单向链表中。如果采用二分查找,那么查找的平均时间复杂度是O(logN)
。
F 二分查找的平均复杂度是O(logN)
,用在数组上。而链表是不能用二分查找的,链表只能顺序访问,顺序查找。
3、在一棵二叉搜索树上查找63,序列39、101、25、80、70、59、63是一种可能的查找时的结点值比较序列。
F 根结点为39,63比39大,因此往39的右子树找,但是25<39,因此不是正确的序列。
4、二叉搜索树的查找和折半查找的时间复杂度相同。
F 二叉搜索树查找的时间复杂度为O(logn)~O(n)
,折半查找的时间复杂度是O (logn)
。
平衡的二叉搜索树与折半查找时间复杂度相同。
5、在散列表中,所谓同义词就是具有相同散列地址的两个元素。
T
6、在散列中,函数“插入”和“查找”具有同样的时间复杂度。
T
7、即使把2个元素散列到有100个单元的表中,仍然有可能发生冲突。
T
8、在散列表中,所谓同义词就是被不同散列函数映射到同一地址的两个元素。
F 在散列表中,所谓同义词就是具有相同散列地址的两个元素。
9、采用平方探测冲突解决策略(hi(k)=(H(k)+i^2)%11
, 注意:不是±i^2
),将一批散列值均等于2的对象连续插入一个大小为11的散列表中,那么第4个对象一定位于下标为0的位置。
T
1 2 mod 11 = 2
2 2 mod 11 = 2 ( 2+1^2 ) mod 11 = 3
3 2 mod 11 = 2 ( 2+2^2 ) mod 11 = 6
4 2 mod 11 = 2 ( 2+3^2 ) mod 11 = 0
10、将 10 个元素散列到 100 000 个单元的哈希表中,一定不会产生冲突。
F 可能会产生冲突。
单选题:
1、已知一个长度为16的顺序表L,其元素按关键字有序排列。若采用二分查找法查找一个L中不存在的元素,则关键字的比较次数最多是:
A.4
B.5
C.6
D.7
B
二分查找的最大比较次数是log2(n)+1。
折半查找在查找不成功时,关键字的比较次数最多,为树的高度log2(n)+1。
log2( 16 ) + 1 = 4 + 1 = 5
2、用二分查找从100个有序整数中查找某数,最坏情况下需要比较的次数是:
A.7
B.10
C.50
D.99
A
log2(n)要向下取整。
log2( 64 ) + 1 < log2( 100 ) + 1 < log2( 128 ) + 1
7 < log2( 100 ) + 1 < 8
3、若在线性表中采用二分查找法查找元素,该线性表应该()。
A.元素按值有序
B.采用顺序存储结构
C.元素按值有序,且采用顺序存储结构
D.元素按值有序,且采用链式存储结构
C
二分查找法不能使用单链表。
4、设有一个已排序的线性表(长度>=2),分别用顺序查找法和二分查找法找一个与K相等的元素,比较的次数分别是S和B,在查找不成功的情况下,S和B的关系是()。
A.S=B
B.S<B
C.S>B
D.S>=B
D
5、在有n(n>1000)个元素的升序数组A
中查找关键字x。查找算法的伪代码如下所示:
k = 0; while ( k<n 且 A[k]<x ) k = k+3; if ( k<n 且 A[k]==x ) 查找成功; else if ( k-1<n 且 A[k-1]==x ) 查找成功; else if ( k-2<n 且 A[k-2]==x ) 查找成功; else 查找失败;
本算法与二分查找(折半查找)算法相比,有可能具有更少比较次数的情形是:
A.当x不在数组中
B.当x接近数组开头处
C.当x接近数组结尾处
D.当x位于数组中间位置
B
6、在下列查找的方法中,平均查找长度与结点个数无关的查找方法是:
A.顺序查找
B.二分法
C.利用哈希(散列)表
D.利用二叉搜索树
C
7、散列冲突可以被描述为:
A.两个元素除了有不同键值,其它都相同
B.两个有不同数据的元素具有相同的键值
C.两个有不同键值的元素具有相同的散列地址
D.两个有相同键值的元素具有不同的散列地址
C
8、设散列表的地址区间为[0,16],散列函数为H(Key)=Key%17。采用线性探测法处理冲突,并将关键字序列{ 26,25,72,38,8,18,59 }依次存储到散列表中。元素59存放在散列表中的地址是:
A.8
B.9
C.10
D.11
D
26 mod 17 = 9
25 mod 17 = 8
72 mod 17 = 4
38 mod 17 = 4 4 + 1 = 5
8 mod 17 = 8 8 + 1 = 9 9 + 1 = 10
18 mod 17 = 1
59 mod 17 = 8 8 + 1 = 9 9 + 1 = 10 10 + 1 = 11
9、将元素序列{18,23,11,20,2,7,27,33,42,15}按顺序插入一个初始为空的、大小为11的散列表中。散列函数为:H(Key)=Key%11,采用线性探测法处理冲突。问:当第一次发现有冲突时,散列表的装填因子大约是多少?
A.0.27
B.0.45
C.0.64
D.0.73
B
18 mod 11 = 7
23 mod 11 = 1
11 mod 11 = 0
20 mod 11 = 9
2 mod 11 = 2
7 mod 11 = 7(第一次发现冲突前有五个关键字)
装填因子:a=n/m,其中n为关键字个数,m为表长。
n=5,m=11
装填因子 = 5 / 11 = 0.45
10、给定散列表大小为11,散列函数为H(Key)=Key%11
。采用平方探测法处理冲突:hi(k)=(H(k)±i^2)%11
将关键字序列{ 6,25,39,61 }依次插入到散列表中。那么元素61存放在散列表中的位置是:
A.5
B.6
C.7
D.8
A
6 mod 11=6
25 mod 11=3
39 mod 11 = 6 6 + 1^2 = 7
61 mod 11 = 6 6 - 1^2 = 5
11、给定散列表大小为11,散列函数为H(Key)=Key%11
。按照线性探测冲突解决策略连续插入散列值相同的4个元素。问:此时该散列表的平均不成功查找次数是多少?
A.1
B.4/11
C.21/11
D.不确定
C
查找成功时的平均查找长度=表中每个元素查找成功时的比较次数之和/表中元素个数。
查找不成功时的平均查找长度相当于在表中查找元素不成功时的平均比较次数。
可以理解为向表中插入某个元素,该元素在每个位置都有可能,然后计算出在每个位置能够插入时需要比较的次数,再除以表长即为查找
不成功时的平均查找长度。
( 5 + 4 + 3 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 ) / 11 = 21 / 11
0 1 2 3 4 5 6 7 8 9 10
x1 x2 x3 x4 空 空 空 空 空 空 空
0→4:5
1→4:4
2→4:3
3→4:2
4→4:1
5→5:1
...
12、现有长度为 7、初始为空的散列表HT
,散列函数H(k)=k%7
,用线性探测再散列法解决冲突。将关键字 22, 43, 15 依次插入到HT
后,查找成功的平均查找长度是:
A.1.5
B.1.6
C.2
D.3
C
22 mod 7 = 1
43 mod 7 = 1 1 + 1 = 2
15 mod 7 = 1 1 + 1 = 2 2 + 1 = 3
( 1 + 2 + 3 ) / 3 = 2
13、从一个具有N个结点的单链表中查找其值等于X的结点时,在查找成功的情况下,需平均比较多少个结点?
A.N/2
B.N
C.(N−1)/2
D.(N+1)/2
D
从一个具有n个节点的单链表中查找其值等于x的节点,在查找成功的情况下,平均需要比较(n+1)/2个节点。
14、采用线性探测法解决冲突时所产生的一系列后继散列地址:
A.必须大于等于原散列地址
B.必须小于等于原散列地址
C.可以大于或小于但不等于原散列地址
D.对地址在何处没有限制
C
15、对包含N个元素的散列表进行查找,平均查找长度为:
A.O(1)
BO(logN)
C.O(N)
D.不确定
D
见6。
利用哈希表查找的平均查找长度与结点个数无关。
16、假定有K个关键字互为同义词,若用线性探测法把这K个关键字存入散列表中,至少要进行多少次探测?
A.K−1
B.K
C.K+1
D.K(K+1)/2
D
总探测次数为1+2+3+...+k = k(k+1)/2
等差数列的前n项和公式:Sn=na1+n(n-1)d/2=(a1+an)n/2
a1=1,an=k,n=k
Sn=(1+k)k/2
程序填空题:
1、折半查找算法
本题要求实现折半查找的递归查找操作。 例如对于下图的有序表:
输入样例:
2
21 70
输出样例:
21 is found
70 is not found
程序如下:
#include <stdio.h>
#include <stdlib.h>
typedef int KeyType;
typedef struct {
KeyType *data; /*表基址*/
int length; /*表长*/
}SSTable;
void CreatSSTable(SSTable *ST);/*有序表创建,由裁判实现,细节不表*/
int BiSearch(SSTable ST,KeyType e,int low,int high);
int main()
{
SSTable ST;
int n,result,i;
KeyType e;
CreatSSTable(&ST);
scanf("%d",&n);
for( i=0;i<n;i++)
{
scanf("%d",&e);
result = BiSearch(ST,e,1,ST.length);
if(result) printf("%d is found\n",e);
else printf("%d is not found\n",e);
}
return 0;
}
int BiSearch(SSTable ST,KeyType e,int low,int high)
{
int mid;
if(low>high) return 0;//low>high
mid=(low+high)/2;
if(ST.data[mid]==e) return mid;
if(e<ST.data[mid]) return BiSearch(ST,e,low,mid-1);//BiSearch(ST,e,low,mid-1)
else return BiSearch(ST,e,mid+1,high);//return BiSearch(ST,e,mid+1,high)
}
2、散列插入
下列代码的功能是利用散列函数hash
将一个元素插入到散列表ht[]
中。其中list
类型的结点包含element
类型的项item
、以及一个next
指针。如果插入成功,则函数返回1,否则返回0。
int insert( struct element item, list_pointer ht[] )
{
int ret, hash_value;
list_pointer ptr, trail, lead;
ret = 1;
hash_value = hash(item.key);
trail = NULL; lead = ht[hash_value];
for ( ; lead; trail = lead, lead = lead->next) {
if (!strcmp(lead->item.key, item.key)) {
printf("The key is in the table\n");
ret = 0;
}
}
if (ret) {
ptr = (list_pointer)malloc(sizeof(struct list));
ptr->item=item;//ptr->item=item
ptr->next = NULL;
if (trail)
trail->next=ptr;//trail->next=ptr
else
ht[hash_value]=ptr;//ht[hash_value]=ptr
}
return ret;
}