我正在研究堆和&堆排序。
有一个数组:arr[8] = {6,9,3,1,8,7,2,11}
当我尝试使用代码和铅笔构建堆时,我遇到了两种堆。
使用代码时, MaxHeap:11 9 7 6 8 3 2 1
使用插入理论时,MaxHeap:11 9 7 8 6 3 2 1
我正在使用的代码:
int[] DoHeapSort(int[] value) {
int length = value.length;
for (int i = length / 2; i > 0; i--) {
maxHeapify(value, i, length);
}
//print Heap
for(int i = 0 ; i<value.length; i++)
System.out.println(value[i]);
return (value);
}
void maxHeapify(int[] array, int index, int heapSize) {
int left = index * 2;
int right = left + 1;
int max = index;
if (left <= heapSize && array[left - 1] > array[index - 1]) {
max = left;
}
if (right <= heapSize && array[right - 1] > array[max - 1]) {
max = right;
}
if (max != index) {
swap(array, index - 1, max - 1);
maxHeapify(array, max, heapSize);
}
}
理论,在这种情况下,为堆创建另一个数组,并按顺序从6到11插入。 (另一方面,代码是就地堆)
两个maxHeap结果都满足堆定义。那么Heap不是唯一的吗?感谢
答案 0 :(得分:9)
那是对的。堆约束(即子节点不大于它们的父节点)不完全指定堆,因此通常有多种可能的排列。
答案 1 :(得分:3)
考虑项目{1, 2, 3}
。 max-heap有两种有效的安排:
3 3
/ \ / \
1 2 2 1
{3, 1, 2} {3, 2, 1}
这两个都满足有效最大堆所需的条件。
给定一个完整的堆(即所有级别都已满),您可以交换任何节点的子节点,但仍然具有有效的堆。或者,更一般地说,只要保持shape属性,就可以交换任何节点的子节点。
请注意&#34;交换孩子&#34;意味着交换锚定在该孩子身上的整个子树。
除了交换子节点,您还可以重新排列节点。
例如,考虑一下这个max-heap:
10
/ \
9 8
/ \ / \
7 6 5 4
最后一级节点的顺序无关紧要;任何一个叶节点都可以是8或9的子节点。这四个孩子有24种可能的排列。
其他安排也是可能的。例如:{10,9,6,7,8,5,4}
。
您获得的安排取决于插入和删除算法的具体情况,以及插入和删除的顺序。或者,在从数组构建堆(即O(n)方法)的情况下,启动时数组中项的顺序。