Binary Heap应该是二叉树还是链表?

时间:2012-02-18 16:54:02

标签: c data-structures tree linked-list

我有一个实现二进制堆的任务。但是,我不确定是否应该将二进制堆实现为二叉树数据结构或简单的双链表。

如果我应该实现二叉树,我应该如何跟踪树的最后一个元素以插入一个新元素?在链表中会更容易。

那么,二进制堆必须是二叉树吗?如果是,如何跟踪最后一个元素?

注意:在我的作业中有一个这样的声明: 但是你不会将二进制堆实现为数组,但是 作为一棵树。

更清楚这是我的节点:

struct Word{
    char * word;
    int count;
    struct Word * parent;
    struct Word * left_child;
    struct Word * right_child;
}

5 个答案:

答案 0 :(得分:2)

根据定义,二进制堆是二叉树。在C中实现此功能的一种方法是将树元素存储在数组中,其中数组索引对应于树元素(对根节点0,其左子节点1,右子节点2等编号)。然后,您可以只存储堆的大小(在创建时初始化为0,并在添加元素时递增)并使用它来查找下一个打开的位置。

对于这样的基本数据结构问题,Wikipedia is your friend

答案 1 :(得分:2)

问题的解决方案。
来自@YunusErenGüzel
解决:

经过五个小时的学习,我找到了一种将堆实现为基于指针的树的方法。 插入算法是:

insert
    node = create_a_node
    parent = get_the_last_parent
    node->parent = parent
    if parent->left==NULL
        parent->left=node
    else
        parent->right=node
end insert

get_last_parent parent,&height
    height++
    if parent->left==NULL || parent->right==NULL
        return parent;
    else
        int left_height=0,right_height=0;
        left = get_last_parent(parent->left,&left_height)
        right = get_last_parent(parent->right,&right_height)
        if left_height == right_height
            height += right_height
            return right
        else if left_height > right_height
            height += left_height
            return left
end get_last_parent

答案 2 :(得分:0)

您应该将其实现为树。这将是简单而有趣的。如果它是最大堆,则Heap只具有任何节点的值小于或等于其父节点的属性。 在数组实现中,我们强加了一些条件。 如果您需要有关特定功能实现的帮助,那么您可以询问它。

您需要向下旅行以添加新节点

用root调用它,要插入值

    insert(node, x){

    if(node->value >= x)
      //insert
      if(node->left == 0)
          node->left = new Node(x);
      else if(node->right == 0)
          node->right = new Node(x);
      else if(node->left->value >= x)
         insert(node->left, x);
      else if(node->right->value >= x)
         insert(node->right, x);
      else
         //insert between node and its any one child
         insertBW(node, node->left, x);
   else  //if x is less than node value
      //insert between node and its parent
      insertBW(node->parent, node, x)
   }

insertBW(p,c)是一个函数,它在p和c之间插入一个包含值x的节点

(我没有测试此代码,请检查错误)

insertBW(Node* p, Node* c, T x)
{
    Node* newnode = new Node(x);
    newNode.x = x;
    if(p == 0)  //if node c is root
    {
       newnode.left = Tree.root.left;
       Tree.root = newnode;
    }
    else
    {
       newnode.parent = p;
       newnode.child  = c;
       if(p.left == c)
       {
           p.left = newnode;
       }
       else p.right = newnode;
    }
}

答案 3 :(得分:0)

这对我来说似乎是一个家庭作业问题&看起来你在问自己之前没有做过任何研发(对不起有点刺耳的话):))

在计算机科学中,堆是一种专门的基于树的数据结构,它满足堆属性:如果B是A的子节点,则键(A)≥键(B)。

我认为您的老师希望您实现优先级队列数据结构,这就是您在同一个问题中同时讨论链接列表和堆的位置。优先级队列可以实现为堆或链接列表,其中根据优先级提取元素,您必须维护按链接列表排序的元素,其中根据您是否实现了一个最大或最小元素在前面最大堆或最小堆OR优先级队列可以简单地实现为堆数据结构。

到最后一点,你说“但你将二进制堆实现为一个数组,而不是一个树。”,似乎是非常无关紧要的。请再次检查所需内容或重现您在作业中提出的确切问题。

答案 4 :(得分:0)

简单地说,关于你的第一个问题 - 没有。堆可以是任何东西(数组,链表,树,当一个人必须即兴创作一群蓬松的小猫)。注意堆的定义:如果“B”是“A”的子元素,那么val(A)> = val(B)(或者,在最小堆的情况下,val(A)< = val( B))。 最常见的是将它称为树(并且也将其称为树),因为很容易将其视为树。此外,时间复杂性&表现很好。

关于你的第二个问题,你没有提供任何信息,所以据我所知,搜索每个节点的解决方案与其他节点一样好......
要获得更好的答案,需要更多信息(您有什么限制,应该支持哪些操作等等)