我正在实现堆数据结构。堆ADT是完整的二叉树,但是在代码的实现中,堆存储在数组中(因此它具有随机访问迭代器)。我正在尝试实现一个给子树的根赋予索引的函数,它可以计算该子树的大小(给出了整个树的大小)。
下面,我提供了为完成该任务而编写的函数的一个版本。我所做的是编写了一个递归函数,该函数将通过添加左子树和右子树的大小加一个来递归计算子树的大小,或者如果它是叶子,则返回1。虽然这将完成我的任务,但我认为这会产生O(n)的时间复杂度,因为它需要访问每个索引来计算子树的大小。
typedef unsigned int uint;
template <typename T>
/**
* @brief sizeOfHeapSubtree - Calculate the size of a subtree of heap from the
* root index
* @param size - the total size of the heap array
* @param root - the index of the root of the heap subtree
* @return the size of the heap subtree starting from the root index
*/
uint sizeOfHeapSubtree(T a[], uint size, uint root){
if(isLeaf(a, size, root)){
//Base case: if the root index of the subtree is a leaf, size is 1
return 1;
} else {
//Recursive case: if the root index of the subtree is NOT a leaf,
// size is leaf subtree's size + right subtree's size
uint leftSubtreeSize;
uint rightSubtreeSize;
uint left = leftChildIndex(a, size, root);
leftSubtreeSize = sizeOfHeapSubtree(a, size, left);
uint right = rightChildIndex(a, size, root);
if(right < size)
rightSubtreeSize = sizeOfHeapSubtree(a, size, right);
else
rightSubtreeSize = 0;
return leftSubtreeSize + rightSubtreeSize + 1;
}
}
鉴于堆存储在数组中并且整个树的大小已知的事实,我想我可以使用数学计算或其他一些不使用索引的方法从索引开始计算子树的大小需要遍历数组。
有人有什么想法吗?