C ++ - 最小堆实现和后期遍历

时间:2014-04-22 23:40:11

标签: c++ algorithm data-structures traversal

所以我有这个小程序,它创建一个最小堆并根据用户输入插入值。如果用户将值更改为10到20,则程序应将所有出现的值更改为10到20,然后进行堆积。当用户给出打印命令时,程序应该在后序中遍历树并打印所有值。所以我编写了程序但是在打印时它给了我不正确的输出。我在这做错了什么:

int pArray[500]; 
int i = 0;

//Definition of Node for tree
struct TNode {
    int data; 
    TNode* left;
    TNode* right;
};

void Heapify(TNode* root, TNode* child);

// Function to create a new Node in heap
TNode* GetNewNode(int data) {
    TNode* newNode = new TNode();
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}

// To insert data in the tree, returns address of root node 
TNode* Insert(TNode* root,int data) {
    if(root == NULL) { // empty tree
        root = GetNewNode(data);
    }
    // if the left child is empty fill that in
    else if(root->left == NULL) {
        root->left = Insert(root->left,data);
    }

    // else, insert in right subtree. 
    else if(root->right == NULL){
        root->right = Insert(root->right,data);
    }

    else {
        root->left = Insert(root->left,data);
    }

    Heapify(root, root->left);
    Heapify(root, root->right);

    return root;
}

void Heapify(TNode* root, TNode* child){
   if(root != NULL && child != NULL){
        if(root->data > child->data){
            int temp = child->data;  
            child->data = root->data;
            root->data = temp;
        }
    } 
}

void Change(TNode* root,int from, int to) {

    if (root == NULL) 
        return;

    else if (root->data == from)
        root->data = to;

    Change(root->left, from, to);
    Change(root->right, from, to);

}

void postOrder(TNode* n){
  if ( n ) {
       postOrder(n->left);
       postOrder(n->right);
       pArray[i] = n->data;
       i++;
    }  
} 

1 个答案:

答案 0 :(得分:2)

  

我在这里做错了什么?

我打算假设您在打印之前已经验证了堆。你的树实现有点令人困惑,但看起来它应该工作。但是,我建议你做的第一件事是在调用Change方法之前打印树,只是为了确保你有一个有效的堆。

假设您有一个有效的堆,您的Change方法存在问题:它永远不会调用Heapify。您最终会更改堆中的值而不是重新排列。所以当你输出它时,它当然会出现故障。

当您更改项目的值时,您必须在更改任何其他值之前将该节点(或节点的值)移动到树中的正确最终位置。您可以使用当前模型(通过重复调用Heapify直到节点处于正确位置)。只要你增加价值。如果您正在减小该值(即将值更改为20到10),那么您就会遇到问题,因为您的代码无法将项目向上移动。

正如@noobProgrammer在他的评论中所指出的,二进制堆通常被实现为数组而不是树。以这种方式实现起来要容易得多,使用的内存更少,效率也更高。如果您对如何完成感兴趣,您应该阅读我关于堆和优先级队列的多部分博客系列。第一个条目Priority queues描述了问题。从那里,您可以按照链接了解二进制堆及其实现方式。代码示例在C#中,但如果您阅读前两篇介绍性文章并理解这些概念,您将能够毫无困难地转换为C ++。