堆排序

来源:互联网 发布:linux file命令 编辑:程序博客网 时间:2024/06/11 01:33

堆分为大根堆(双亲节点大于孩子节点)和小根堆(双亲节点小于孩子节点)

一般用数组来表示堆。当一个节点的下标为i时,它的左右孩子下标为2*i+1,2*i+2

由于我将进行从小到大的排序,因此我将使用的是大根堆。
此处我所将要进行的堆排序思路大致如下:
1)假设待排序数据元素有n个,那么我们就从n/2-1下标处开始倒着进行进行调整
2)当我们进行了n/2logn次调整之后,此时最大的值就在堆顶,交换堆顶数据和n-1处的数据,此时最大的数值就在数组的末尾了。
3)至此,我们已经大致上建立了一个大根堆,但是仍需进一步调整。由于n-1下标处已经是最大,这下我们从下标为0开始调整,直到n-2处,每调整一次则交换一次。

代码如下:

void Show_arr(int *arr, int n){    for (int i = 0; i<n; i++)    {        printf("%d ", arr[i]);    }    printf("\n");}void swap(int *x, int *y){    int tmp;    tmp = *x;    *x = *y;    *y = tmp;}void Heap_Adjust(int *arr, int start, int end){    int tmp = arr[start];    int i = 2 * start + 1;    while (i <= end)    {        if (arr[i] < arr[i + 1] && i + 1 <= end)        {            i++;        }        if (arr[i] > tmp)        {            arr[start] = arr[i];        }        else        {            break;        }        start = i;        i = 2 * start + 1;    }    arr[start] = tmp;}void HeapSort(int *arr, int n){    //建立堆(大根堆)n/2*logN    for (int i = n / 2 - 1; i >= 0; --i)    {        Heap_Adjust(arr, i, n - 1);    }    swap(&arr[0], &arr[n - 1]);    //调整堆 n*logN    for (int j = n - 2; j>0; --j)    {        Heap_Adjust(arr, 0, j);        swap(&arr[0], &arr[j]);    }}int main(){    int arr[] = { 16, 3, 6, 18, 2, 45, 4, 38, 2, 99, 34, 36, 27, 1 };    int n = sizeof(arr) / sizeof(arr[0]);    HeapSort(arr, n);    Show_arr(arr, n);    return 0;}

运行结果如下:
这里写图片描述

0 0
原创粉丝点击