用heapsort排序数组的一部分,bug

时间:2017-03-25 13:21:53

标签: java algorithm sorting quicksort heapsort

这是我的内部代码。我无法使代码的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;
    }

}

有什么想法吗?

3 个答案:

答案 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元素会出现意外情况,甚至可能与2nd5th元素交换,这会导致结果不正确。

如果您想构建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