堆排序C - 输出不正确

时间:2015-05-10 18:19:14

标签: c arrays sorting heapsort

我试图按升序为10个元素的数组实现堆排序。 我按照这些步骤 -

heap_sort(ARR,size_array):

 build_max_heap(arr)
    for(parent=size_array to 1):
       swap(arr[1],arr[parent])
       size_array = size_array - 1;
       max_heapify(arr,1,size);

但我的输出完全搞砸了。 我无法弄清楚我哪里出错了。

这是我的输入 -

20  15  10  1   15  9   2   6   7   9

我的build_max_heap输出 -

20  15  10  7   15  9   2   6   1   9

我的排序数组与build_max_heap输出相同 -

20  15  10  7   15  9   2   6   1   9

我做错了什么?

这是我的代码:

    void max_heapify(int *arr,int i,int size)
{
    //i is the index of parent node. 2i is left child, 2i+1 is right
    int left = (2*i)+1;
    int right = (2*i)+2;
    int max;
    int temp;

    //check which node is the max, parent or one of its children. store max idx.
    if ((left<=size)&&(arr[left]>arr[i]))
        max = left;
    else
        max = i;
    if ((right<=size)&&(arr[right]>arr[max]))
        max = right;

    //swap parent with max.
    if(max!=i)
    {
        temp = arr[max];
        arr[max]=arr[i];
        arr[i]=temp;
        max_heapify(arr,max,size);
    }

}

void build_max_heap(int *arr,int size)
{
    for(int i = size/2; i>=0; i--)
    {
        max_heapify(arr,i,size);
    }
}

void heap_sort(int *arr, int size)
{
    int temp;
    build_max_heap(arr,size);
    int i = size;
    while(size>0)
    {
        //swap
        temp = arr[i];
        arr[i] = arr[0];
        arr[0] = temp;
        //reduce size
        size = size -1;
        //heapify
        max_heapify(arr,0,size);

    }
}

2 个答案:

答案 0 :(得分:3)

在你的heap_sort中i应该在循环中设置为size。你有它的方式你每次都用arr [9]交换arr [0]。相反,每次大小减少1时,arr [0]应与arr [size]交换。

int i = size; //Here is your main problem
while(size>0)
{
    //swap
    temp = arr[i];
    arr[i] = arr[0];
    arr[0] = temp;
    //reduce size
    size = size -1;
    //heapify
    max_heapify(arr,0,size);

}

答案 1 :(得分:2)

您的代码多次访问元素arr[size],这是有效范围之外的一项0 <= index < size。特别是:

if ((left<=size)&&(arr[left]>arr[i]))
    max = left;
else
    max = i;
if ((right<=size)&&(arr[right]>arr[max]))
    max = right;

在此,您应该将所有... <= size替换为... < size

int temp;
build_max_heap(arr,size);
int i = size;
while(size>0)
{
    //swap
    temp = arr[i];
    arr[i] = arr[0];
    arr[0] = temp;
    //reduce size
    size = size -1;
    //heapify
    max_heapify(arr,0,size);

}

在这里,您使用两个变量isize,但只更新size。索引i将始终超出范围,因为i < size永远不会成立。您应该通过循环仅使用和更改一个变量。

您可以完全省略i,但请注意您将始终如何访问数组之外​​的项目。因此,在交换元素之前,应减少size

(你可以将while (size > 0) { size = size - 1; ...}约定为while (size--) ...。这是向后迭代的一个有用的习惯用法:向后迭代在循环体之前判断索引;向前迭代在循环体之后增加索引。)

全部放在一起:

void max_heapify(int *arr, int i, int size)
{
    //i is the index of parent node. 2i is left child, 2i+1 is right
    int left = 2*i + 1;
    int right = 2*i + 2;
    int max;

    if (left < size && arr[left] > arr[i])
        max = left;
    else
        max = i;

    if (right < size && arr[right] > arr[max])
        max = right;

    if (max != i) {
        int temp = arr[max];
        arr[max]=arr[i];
        arr[i]=temp;

        max_heapify(arr,max,size);
    }

}

void build_max_heap(int *arr,int size)
{
    int i = size / 2; 

    while (i--) {
        max_heapify(arr, i, size);
    }
}

void heap_sort(int *arr, int size)
{
    build_max_heap(arr, size);

    while (size--) {
        int temp = arr[size];
        arr[size] = arr[0];
        arr[0] = temp;

        max_heapify(arr, 0, size);
    }
}