通过二叉树的数组表示的最小堆; MoveDown函数无限循环

时间:2013-04-08 20:50:04

标签: c++ arrays binary-tree

我正在使用数组数据结构实现最小堆,但是我的moveDown方法存在问题(如果root的子节点小于它,则在根节点处使用将集合返回到堆)。我假设读者会知道什么是最小堆,但我会描述它以防万一有人没有或我的理解不正确。

最小堆(在本例中)是由数组表示的二叉树,其中:

  1. 根节点是数据结构中的最小值
  2. 节点必须始终小于其子节点
  3. 给定一个数组索引为I的节点,它的左子节点将在索引I * 2 + 1处,而右子节点在I * 2 + 2
  4. 我遇到的当前问题是我的moveDown函数在交换时会遇到无限循环。我很难找到一个逻辑错误,所以我担心它可能会更接近根源(双关语意图,我无法帮助自己)。

    heap.cpp文件的值得注意的数据成员:

    int size;
    MiniVector array;// The implementing custom array
    void moveDown(int root);
    

    我的heap.cpp文件中的moveDown函数:

    void BinaryHeap::moveDown( int root ){
    
        int temp = root;
        int tempLC = temp*2 + 1;//LeftChild
        int tempRC = temp*2 + 2;//RightChild
    
        //Not a leaf
        while( ( tempLC < array.size() && tempRC < array.size() )
            &&
        ( (array[temp] > array[tempLC]) || (array[temp] > array[tempRC]) ) ){
    
            int hold = array[temp];
    
            if( array[temp] > array[tempRC] ){
    
                array[temp] = array[tempRC];
                array[tempRC] = hold;
                temp = tempRC;
            }
    
            else{
    
                array[temp] = array[tempLC];
                array[tempLC] = hold;
                temp = tempLC;
            }
    
            int tempLC = temp*2 + 1;//LeftChild
            int tempRC = temp*2 + 2;//RightChild
        }
    }
    

1 个答案:

答案 0 :(得分:1)

您重新声明了变量。在while循环的底部

    int tempLC = temp*2 + 1;//LeftChild
    int tempRC = temp*2 + 2;//RightChild

应该是

    tempLC = temp*2 + 1;//LeftChild
    tempRC = temp*2 + 2;//RightChild

在Java中不会发生。

如果你把你的循环重写为一个无限的for循环并且中间有一个中断

,也不会发生
for (;;)
{
    int tempLC = temp*2 + 1;//LeftChild
    int tempRC = temp*2 + 2;//RightChild
    if (...)
        break;
    ...
}

但每当我建议这种循环是一个好主意时,我就会受到抨击。上次有人认为它“几乎是一种反模式”,这是一种更有礼貌的回应。