【10】算法排序 (堆排序)

思想:

 

复杂度:

  O(logN)

  O(N)

堆的性质:

  1: 堆中某个节点的值总是不大于或不小于其父节点的值;

  2: 堆总是一棵完全二叉树。

  堆分类为:大顶堆和小顶堆

 

 

解析:

第一步:建堆(举例大顶堆)

从父节点9开始从左往右,与左右孩子相比较,寻找比自己大的数,进行交换;

 

 

第二步:排序

将顶节点与尾节点交换, 尾节点的值切下来,放在后面作为已排好的结果;

再对剩余的堆值,进行建堆维护,得出第一轮排序结果;

重复以上操作;

 

完整代码

#include <stdio.h>

void PrintSort(int * a, int n)
{
        printf("\n");
        int i = 0;
        for(i=0; i<n; i++) {
                printf(" %d ", a[i]);
        }
        printf("\n");
}

void swap(int * a, int * b)
{
        int t = *a;
        *a = *b;
        *b = t;
}

/*
a:数组
n:数组长度
i:下标
*/
void heapify(int *a, int n, int i)
{
        // 找最大的值
        int largest = i;
        int lson = i*2+1;
        int rson = i*2+2;
        if (lson < n && a[largest] < a[lson])
                largest = lson;
        if (rson < n && a[largest] < a[rson])
                largest = rson;
        // 父节点不是最大的, 有个孩子比它大
        if (largest != i) {
                swap(&a[largest], &a[i]);
                // 维护当前堆的性质
                heapify(a, n, largest);
        }
}

void HeapSort(int *a, int n)
{
        // 建堆
        int i;
        for (i=n/2-1; i>=0; i--) {
                heapify(a, n, i);
        }

        // 注释
        printf("建堆的结果:");
        PrintSort(a, n);

        // 排序
        printf("排序的过程:");
        for(i=n-1; i>0; i--) {
                swap(&a[i], &a[0]);
                // 维护剩余(堆顶)元素的性质
                heapify(a, i, 0);

                PrintSort(a, n);
        }
}
void main()
{
        int n = 8;
        int a[] = {9, 2, 1, 3, 8, 4, 7, 6};
        HeapSort(a, n);
        printf("排序结果:  ");
        PrintSort(a, n);
}

 

posted @ 2020-08-31 16:13  欧阳图图的少年成长记  阅读(151)  评论(0编辑  收藏  举报