这是我最近遇到的面试问题之一。
给定完整或几乎完整的二叉树的根地址,我们必须编写一个函数将树转换为最大堆。
这里没有涉及数组。该树已构建。
例如
1 / \ 2 5 / \ / \ 3 4 6 7
可以有任何可能的最大堆作为输出-
7 / \ 3 6 / \ / \ 2 1 4 5
要么
7 / \ 4 6 / \ / \ 2 3 1 5
等等…
我写了一个解决方案,但结合使用了前后遍历,但是我猜它运行在O(n ^ 2)中。我的代码给出以下输出。
7 / \ 3 6 / \ / \ 1 2 4 5
我一直在寻找更好的解决方案。有人可以帮忙吗?
编辑:
void preorder(struct node* root) { if(root==NULL)return; max_heapify(root,NULL); preorder(root->left); preorder(root->right); } void max_heapify(struct node* root,struct node* prev) { if(root==NULL) return ; max_heapify(root->left,root); max_heapify(root->right,root); if(prev!=NULL && root->data > prev->data) { swapper(root,prev); } } void swapper(struct node* node1, struct node* node2) { int temp= node1->data; node1->data = node2->data; node2->data = temp; }
我认为可以通过以下过程在O(NlogN)时间内完成。 http://www.cs.rit.edu/~rpj/courses/bic2/studios/studio1/studio121.html
假设树中有一个元素,其左子树和右子树都是堆。
E H1 H2
通过使元素E游至正确位置,可以在logN时间内对由E,H1和H2形成的Tree进行堆积。
因此,我们开始自下而上构建堆。转到最左侧的子树,并通过简单比较将其转换为堆。这样做也是因为它是同级的。然后上升并将其转换为堆。
同样,对每个元素都执行此操作。
编辑:如评论中所述,复杂度实际上是O(N)。