将在数组中实现的堆转换为树

时间:2017-12-28 10:57:07

标签: c algorithm tree heap min-heap

我有这个功课,我必须转换数组中表示的最小堆:

DEFINE #SIZE

typedef int Heap[SIZE]

并在如下的树中实现它:

typedef struct node{
   int val;
   struct no *left, *right;
} Node, *Tree;

并提醒一下min-heaps数组的索引如下:

#DEFINE PARENT(i) (i-1)/2
#DEFINE LEFT(i) 2*i + 1
#DEFINE RIGHT(i) 2*i + 2

那么,我该怎么做?

我开始这样的事情:

Tree heapToTree(int * heap){
   Tree *t = malloc(sizeof(struct node));
   t->val = heap[0];
   Tree *aux = t; //save initial tree position
   for(i=0;i<SIZE;i++){
      aux->left=malloc(sizeof(struct Node));
      aux->left->val=heap[i*2 +1];
      aux->right=malloc(sizeof(struct Node));
      aux->right->val=heap[i*2 +2];
}

我是在正确的道路上吗?我认为这应该以递归的方式完成,但是如何?

提前致谢

1 个答案:

答案 0 :(得分:1)

您缺少的一件事是 - 最初没有将新创建的节点的链接(leftright)发送到NULL。无论如何,任何类型的树实现都非常有用 - 有助于遍历,查找元素(这也是遍历)等。

同样在循环中你没有改变aux的值(或至少你没有显示) - 因此你正在写旧值并且有内存泄漏。

除了不检查malloc的返回值之外,还有另外一点。您应该检查malloc的返回值 - 如果NULL那么您应该从通常的代码流中明确地处理(错误处理)。

考虑到堆是在一个数组(0-index)中实现的,你可以这样做将它转换为树。

struct node *convIntoTree(int pos,int sz, int *heap){
    if(pos >= sz ) return NULL;
    struct node* root = malloc(sizeof *root);
    if( root == NULL ){
       perror("Malloc failed");
       exit(EXIT_FAILURE);
    }
    root->data = heap[pos];
    root->left = convIntoTree(pos*2+1,sz);
    root->right = convIntoTree(pos*2+2,sz);
    return root;  
}

像这样称呼

   struct node *root = convToTree(0,heapsize,heap);

解决方案是简单地应用遍历堆的每个节点的强力方法,然后为其分配内存并递归地填充它的左右子节点。