我真的一直把头发拉出来一段时间,并且会因此而死于某些答案。
我有一个基于数组的堆实现。插入时我的堆排序似乎正在工作,但是当我弹出顶部值时,我无法使下堆排序工作。我已经将完整的代码放在这里并且如果有人可以纠正downHeap方法以便在删除顶部值时能够对此数组进行排序,那么我会很喜欢它:
public class HeapSortArray {
static int sizeOfTree = 0;
private static int arrayBufferSize = 50;
public static int[] heap = new int[arrayBufferSize];
static int[] numbers = new int[]{ 0, 7, 9, 7, 5, 2, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
public static void main(String[] args) {
insert(0); //set 0 of the array to nothing
//fill array with numbers
for (int i = 1; i < numbers.length; i++) {
insert(numbers[i]);
if (i > 1) {
upHeap(i);
}
}
System.out.println("Heap Printed once inserted: ");
for(int i=1; i < numbers.length; i++){
System.out.println(heap[i]);
}
System.out.println("----------------------");
System.out.println("Heap Printed as top value is popped out: ");
//pop lowest value
for(int i = numbers.length; i != 1; i--){
removeMin();
}
}
public static void upHeap(int childLocation) {
int parentLocation = childLocation / 2;
int child = childLocation;
int parentTemp = heap[parentLocation];
int childTemp = heap[childLocation];
int parentValue = heap[parentLocation];
int childValue = heap[child];
if (parentValue > childValue) {
heap[parentLocation] = childTemp;
heap[childLocation] = parentTemp;
}
if (parentLocation != 1) {
upHeap(parentLocation);
}
}
public static void downHeap(int location){
if(location > 0){
int parentLocation = location;
int leftchildLocation = 2*location;
int rightchildLocation = 2*location+1;
int parentValue = heap[parentLocation];
int leftchildValue = heap[leftchildLocation];
int rightchildValue = heap[rightchildLocation];
int parentTemp = heap[parentLocation];
int leftChildTemp = heap[leftchildLocation];
int rightChildTemp = heap[rightchildLocation];
if(leftchildValue < rightchildValue && leftchildValue < parentValue){
heap[parentLocation] = leftchildValue;
heap[leftchildLocation] = parentTemp;
downHeap(leftchildLocation);
}
if(rightchildValue < leftchildValue && rightchildValue < parentValue){
heap[parentLocation] = rightchildValue;
heap[rightchildLocation] = parentTemp;
downHeap(rightchildLocation);
}
}
}
public static int removeMin() {
sizeOfTree--;
if(sizeOfTree > 1){
heap[1] = heap[sizeOfTree];
downHeap(1);
}
int toReturn = heap[1];
System.out.println(toReturn);
return toReturn;
}
public static void insert(int toInsert) {
heap[sizeOfTree] = toInsert;
if(sizeOfTree > 1){
upHeap(sizeOfTree);
}
sizeOfTree++;
}
}
非常感谢任何能够对这一点有所了解的人。
编辑: 如果在第38行,上述实施将起作用:
int parentLocation = childLocation / 2;
更改为:
int parentLocation = childLocation -1;
我知道第二种方法不是它的意图,但为什么我的childLocation / 2没有给我父母呢?
答案 0 :(得分:4)
以下是downHeap所需的检查:
否则,左边的子节点是堆的大小并且左边的子节点小于父节点
public static void downHeap(int location){
if(location < sizeOfTree){
int p = location;
int l = 2*p;
int r = 2*p+1;
int s = sizeOfTree;
if(r<s && heap[r]<heap[p] && heap[r]<heap[l]){
int temp = heap[r];
heap[r] = heap[p];
heap[p] = temp;
downHeap(r);
}else if(l<s && heap[l]<heap[p]){
int temp = heap[l];
heap[l] = heap[p];
heap[p] = temp;
downHeap(l);
}
}}
同样在removeMin()中,你应该在覆盖之前复制最小值:
public static int removeMin() {
sizeOfTree--;
int toReturn = heap[1];
if(sizeOfTree > 1){
heap[1] = heap[sizeOfTree];
downHeap(1);
}
System.out.println(toReturn);
return toReturn;
}