这是我的内部代码。我无法使代码的heapsort部分工作。
partition()
和sort()
的工作原理应该如此,但是heapsort部分没有正确排序。我得到排序数组(大小= 10),如下所示:
10
18
26
35
25
39
49
49
57
89
除少数数字外,大多数都是排序的。我只是尝试在每个heapsort()
调用中对数组的一部分进行排序。
public class IntroSort {
public static void sort(int[] arrayToSort){
int depth = ((int) Math.log(arrayToSort.length))*2;
sort(arrayToSort, depth, 0, arrayToSort.length-1);
}
private static void sort(int[] arrayToSort, int depth, int start, int end){
int length = arrayToSort.length;
if(length <= 1){
return;
}else if(depth == 0){
heapSort(arrayToSort, start, end);
}else{
if(start >= end)
return;
int pivot = arrayToSort[(start + end)/2];
int index = partition(arrayToSort, start, end, pivot);
sort(arrayToSort, depth-1, start, index-1);
sort(arrayToSort, depth-1, index, end);
}
}
private static void heapSort(int[] arrayToSort, int start, int end){
for (int i = end / 2 - 1; i >= start; i--)
heapify(arrayToSort, end, i);
for (int i=end-1; i>=start; i--){
int temp = arrayToSort[start];
arrayToSort[start] = arrayToSort[i];
arrayToSort[i] = temp;
heapify(arrayToSort, i, start);
}
}
private static void heapify(int[] arrayToSort, int n, int i){
int largest = i;
int l = 2*i + 1;
int r = 2*i + 2;
if (l < n && arrayToSort[l] > arrayToSort[largest])
largest = l;
if (r < n && arrayToSort[r] > arrayToSort[largest])
largest = r;
if (largest != i){
int swap = arrayToSort[i];
arrayToSort[i] = arrayToSort[largest];
arrayToSort[largest] = swap;
heapify(arrayToSort, n, largest);
}
}
private static int partition(int[] arrayToSort, int start, int end, int pivot){
while(start <= end){
while(arrayToSort[start] < pivot){
start++;
}
while(arrayToSort[end] > pivot){
end--;
}
if(start <= end){
int temp = arrayToSort[start];
arrayToSort[start] = arrayToSort[end];
arrayToSort[end] = temp;
start++;
end--;
}
}
return start;
}
}
有什么想法吗?
答案 0 :(得分:1)
卡尔顿 我在一些数组上运行你的代码,并对该数组中的数据进行了排序。 您能举例说明您的算法无法正常工作吗?
int[] arr = new int[]{17,1,15,1,2,3,18,100,100,454};
heapSort(arr, 0, arr.length);
for (int i:arr)
System.out.print(i+" ");
结果我得到了:
1 1 2 3 15 17 18 100 100 454
处理完成,退出代码为0
答案 1 :(得分:1)
因为您的heapify
方法无法仅为输入数组的部分构建最大堆。
让我们来看一个示例:假设您有一个长度为10的数组,并且您希望将部分从3到6排序,您将从您的代码中调用heapSort(array, 3, 6)
:
private static void heapSort(int[] arrayToSort, int start, int end){
for (int i = end / 2 - 1; i >= start; i--)
heapify(arrayToSort, end, i);
for (int i=end-1; i>=start; i--){
int temp = arrayToSort[start];
arrayToSort[start] = arrayToSort[i];
arrayToSort[i] = temp;
heapify(arrayToSort, i, start);
}
}
首先在第一个for循环中调用heapify(array, 6, 2)
,然后在heapify
实现中,将2nd
元素与{{{ 1}}和5th
元素,甚至可以用后两个中的一个交换它。因此,当您要对第3部分到第6部分进行排序时,6th
元素会出现意外情况,甚至可能与2nd
或5th
元素交换,这会导致结果不正确。
如果您想构建6th
,我认为首先构建portionHeapSort
可能会更好,然后根据它构建heapSort
,如下面的代码:
portionHeapSort
希望这对你有所帮助: - )
答案 2 :(得分:1)
我最近写了一个代码来解决这个问题。 Here's a link to my post.
为了简单起见,我还将代码粘贴在这里:
def buildMaxHeap(arr, arrayLength, indexStart, attr):
for i in range(arrayLength):
# if child is bigger than parent
if getattr(arr[indexStart + i], attr) > getattr(arr[indexStart + int((i - 1) / 2)], attr):
j = i
# swap child and parent until
# parent is smaller
while getattr(arr[indexStart + j], attr) > getattr(arr[indexStart + int((j - 1) / 2)], attr):
(arr[indexStart + j],
arr[indexStart + int((j - 1) / 2)]) = (arr[indexStart + int((j - 1) / 2)], arr[indexStart + j])
j = int((j - 1) / 2)
def heapSort(arr, arrayLength, indexStart, attr):
buildMaxHeap(arr, arrayLength, indexStart, attr)
for i in range(arrayLength - 1, 0, -1):
# swap value of first indexed
# with last indexed
arr[indexStart + 0], arr[indexStart + i] = arr[indexStart + i], arr[indexStart + 0]
# maintaining heap property
# after each swapping
j, index = 0, 0
while True:
index = 2 * j + 1
# if left child is smaller than
# right child point index variable
# to right child
if (index < (i - 1) and getattr(arr[indexStart + index], attr) < getattr(arr[indexStart + index + 1], attr)):
index += 1
# if parent is smaller than child
# then swapping parent with child
# having higher value
if index < i and getattr(arr[indexStart + j], attr) < getattr(arr[indexStart + index], attr):
arr[indexStart + j], arr[indexStart + index] = arr[indexStart + index], arr[indexStart + j]
j = index
if index >= i:
break