2-选择题练手

1.HASH函数冲突处理方式不包括以下哪一项

A.开放定址法

B.链地址法

C.插入排序法

D.公共溢出区发

:C

HASH函数冲突处理方式有:

  • 开放定址法:(线性探测再散列,二次探测再散列,伪随机探测再散列)线性探测再散列,就是这个值有冲突就依次加1向下一个寻址直到不冲突为止,但效率偏低 ;所以会使用二次探测再散列,就是使用平方的方式等。
  • 再哈希法:就是这个hash函数有冲突,就换一个hash函数试试。
  • 链地址法:(Java hashmap就是这么做的)使用链表处理冲突,只要有冲突就增加一个链表节点。
  • 建立一个公共溢出区:将哈希表分为基本表和溢出表,凡是有冲突的就直接放到溢出区。

插入排序是排序算法的一种,与哈希无关。

2.下设栈S的初始状态为空,元素a,b,c,d,e,f依次入栈S,出栈的序列为b,d,c,f,e,a,则栈S的容量至少为

A.6

B.5

C.4

D.3

:D

3.中序遍历二叉排序树可以得到一个从小到大的有序序列。

4.下列选项中,不可能是快速排序第2趟排序结果的是 

A.2,3,5,4,6,7,9

B.2,7,5,6,4,3,9

C.3,2,5,4,7,6,9

D.4,2,3,5,7,6,9

:C

每经过一趟快排,轴点元素都必然就位,也就是说,一趟下来至少有1个元素在其最终位置。

快排的阶段性排序结果的特点是,第i趟完成时,会有i个以上的数出现在它最终将要出现的位置,即它左边的数都比它小,它右边的数都比它大。

题目问第二趟排序的结果,即要找不存在2个这样的数的选项。A选项中2、3、6、7、9均符合,所以A排除;B选项中,2、9均符合,所以B排除;D选项中5、9均符合,所以D选项排除;最后看C选项,只有9一个数符合,所以C不可能是快速排序第二趟的结果。

5.若一棵二叉树具有12个度为2的节点,6个度为1的节点,则度为0的节点个数是

A.11

B.10

C.13

D.不确定

:C

由于N=N0+N1+N2,N=2*N2+N1+1,推出N0=N2+1,即叶子节点个数=度为2结点个数+1。

6.大小为MAX的循环队列中,f为当前队头元素位置,r为当前队尾元素位置(最后一个元素的位置),则任意时刻,队列中的元素个数为

A.r-f

B.(r-f+MAX+1)%MAX

C.r-f+1

D.(r-f+MAX)%MAX

:B

书上公式:(r-f+MAX)%MAX,r指向队尾元素的下一个位置。

本题公式:(r-f+MAX+1)%MAX,r指向队尾元素的位置。

通常最后一个元素不存东西,方便判断队列空还是满。这题是个例外。

 7.已知某个哈希表的n个关键字具有相同的哈希值,如果使用二次探测再散列法将这n个关键字存入哈希表,至少要进行几次探测

A.n-1

B.n

C.n+1

D.n(n+1)

E.n(n+1)/2

F.1+n(n+1)/2

:E

问的是至少需要多少次探测,即我们假设在上一次探测的基础上,每进行一次二次探测都能直接找到对应的位置。
第一个:直接找到位置,入坑,1次;
第二个:和第一个同hash,找到的位置被第一个给占了,通过二次探测直接找到下一个,入坑,2次;
第三个:第一个被占了,第二个也被占了,通过二次探测直接找到第三个,入坑,3次;
......
第n个:n次;
一共:(1+n)*n / 2 次

注:二次探测属于开放地址法,开放地址法(除了随机探测)都是(1+n)*n / 2 次。

8.已知小根堆为8,15,10,21,34,16,12,删除关键字8之后需重建堆,最后的叶子节点为

A.34

B.21

C.16

D.12

:C

将堆画成完全二叉树的形式,堆删除堆顶元素后,是将二叉树最后的叶子节点12放到堆顶,然后将12与其子节点15和10相比较,当15>12时,堆顶12不动,将12与10判断,12>10,不符合小根堆,所以将10和12对调,然后还要将12与其子节点16比较。 所以总共比较3次,最后的叶子节点为16。

 为什么将最后的叶子节点和删除的根节点换?
因为移除根节点后,树就不再是完整的了,数组(这里考虑的是用数组实现堆)中就会有一个空的数据单元,可以把数组中所有的数据都向前移动一个单元,但是这种方法比较慢,所以考虑用最后一个节点填补空的单元,再向下筛选。

9.堆排序平均执行的时间复杂度和需要附加的存储空间复杂度分别是

A.O(n^2)和O(1)

B.O(nlog(n))和O(1)

C.O(nlog(n))和O(n)

D.O(n^2)和O(n)

:B

:堆排序的时间复杂度为O(nlog(n)),与树结构有关;空间复杂度为O(1),只在原数组上操作。

10.将N条长度均为M的有序链表进行合并,合并以后的链表也保持有序,时间复杂度为

A.O(N * M * logN)

B.O(N*M)

C.O(N)

D.O(M)

:A

方法1:

1. 在每一个链表中取出第一个值,然后把它们放在一个大小为N的数组里,然后把这个数组当成heap建成小(大)根堆。此步骤的时间复杂度为O(N)。

2. 取出堆中的最小值(也是数组的第一个值), 然后把该最小值所处的链表的下一个值放在数组的第一个位置。如果链表中有一个已经为空(元素已经都被取出),则改变heap的大小。此步骤的时间复杂度为O(lg N)。

3. 不断的重复步骤二,直到所有的链表都为空。

建堆只建一次,复杂度为O(N);调整堆MN-1次,复杂度为(MN-1)*O(lg N)。所以为O(MN*lg N)。

在堆排序中也是一样的,总共n个数,需要得到n个有序的数,那么构建堆需要O(n),重建堆需要(n-1)*O(lgn),所以总共复杂度O(nlgn);如果我只需要前面k个数有序的,那么重构堆需要k*O(lgn),那么总共复杂度就是O(klgn)

方法2:
m*n个数归并排序复杂度是O(m*nlog(m*n)),即O(m*nlogm)+O(m*nlogn). n个m长度的序列已经是有序的了,每个m长度的序列进行归并排序的时间复杂度为O(mlogm),则n个m长度的序列的时间复杂度为n*O(mlogm),前后相减O(m*nlogm)+O(m*nlogn)-n*O(mlogm)=O(m*nlogn)即为答案。
(这里可以看成对n个区间进行归并排序,而每个区间的排序都是独立的)。

方法3:
代入 N=1,不需要排序,凡是非常数的都是错误答案。排除BD
代入 M=1,类似正常排序,NlogN

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值