参考答案:
【问题1】
(1)A->int_array[0]
(2)A->int_array[0]= A->int_array[A->array_size-1]
(3)A-> array_size-1
(4)A->int_array[PARENT(i)]<key
(5)A->int_array[i]=key
【问题2】
(6)O(1) (7)O(lgn) (8)O(lgn)
【问题3】
(9)3
详细解析:
【问题1】
本题考查堆数据结构的相关内容。题目告诉我们函数heapMaximum(A)的功能返回大顶堆A中的最大元素;函数heapExtractMax(A)的功能是去掉并返回大顶堆A的最大元素,将最后一个元素“提前”到堆顶位置,并将剩余元素调整成大顶堆;而函数maxHeaplnsert(A, key)的功能是把元素key插入到大顶堆A的最后位置,再将A调整成大顶堆。
第(1)空在函数heapMaximum(A)中,而且从程序中可以看出,是返回的结果,那么应该是大顶堆中最大元素,就应该是A->int_array[0]。
第(2)空在函数heapExtractMax(A)中,根据该函数的功能描述,并结合程序可以看出,第(2)空是在将最大元素移出后,那么接下了来应该处理将最后一个元素“提前”到堆顶位置,那么就应该是A->int_array[0] = A->int_array[A->array_size -1]。
第(3)(4)(5)空都在函数maxHeaplnsert(A, key)中。从程序和函数的功能我们可以知道,从程序第(3)空最后,其作用是找到元素key的插入位置并插入该元素。第(3)空是给变量i赋值,从后面的程序中我们可以看出i是做为数组下标的;而查找元素插入的位置应该从后往前的顺序,因此i的初值应该为A->array_size – 1,从循环中也可以看出i的值在逐渐变小。
第(4)空是循环的一个条件,而循环的作用是找到合适的插入位置,由于大顶堆的特点是根节点的值大于左右子树节点上的值,那么找到比待插入元素大的父节点时,应该就找到了它插入的合适位置,而每次操作后i的值被赋值为PARENT(i),很显然这是找到其父节点的存储位置,因此循环结束的一个条件就是找到一个比key值大的父节点,那么循环继续的条件就是父节点的值小于key的值,所以本空的答案为A->int_array[PARENT(i)]<key 。
【问题2】
根据题目描述,heapMaximum用来返回大顶堆A中的最大元素,而且大顶堆已经建成,只需要通过一步操作就能取到。因此时间复杂度是O(1),
而对于heapExtractMax是用来去掉大顶堆A的根,然后重新建堆,当输出堆顶结点并将堆中最后一个结点设置为根结点之后,根结点将有可能不再满足堆的性质,所幸的是整个序列也只有根结点一处的堆结构可能被破坏,其余结点仍然满足堆性质,故可利用性质进行堆调整,算法的基本思想为:将新堆顶沿着其关键字较大的孩子结点向下移动,直到叶子结点或者满足堆性质为止。因此相对于有N个元素的堆,只需要log2n次比较即可完成,因此时间复杂度是O(log2n),这与书本说堆排序的算法时间复杂度是:O(nlog2n)不冲突,因为书本上是对堆中所有元素进行操作,而这里其实相当于只将一个元素入堆,因此少了一个n。同样的道理可以得到maxHeaplnsert的时间复杂度O(log2n)。
【问题3】
这个我们可以结合题目给出的那个大顶堆的图来看,首先将key插入在最后,应该是8这个节点的右子树,由于10比8大,所以应该互换,再与节点9比较,由于10仍然大于9,所以也应该互换,这个时候再与其父节点15比较,由于小于15,所以不需要再调整,那么调整后的结果就是10这个元素应该作为根节点15的右子树。那么很显然10应该是在堆A中第3个位置。