堆排序

点击查看代码
#include <iostream>
using namespace std;
/*小顶堆函数降序排序修改:
1、MaxHeap函数中改为if (c < end && a[c] > a[c + 1])//如果有右孩子,则用较小者与父结点进行比较
2、MaxHeap函数中改为if (tmp > a[c])//如果父结点大于孩子结点,则互换两结点的值
*/

//构造大顶堆,顶点下标范围[start,end]
/*
函数功能:构造大顶堆
参数列表:
a:指向待排序序列的指针
start:第一个非叶子结点
end:待排序序列最后一个元素
*/
void MaxHeap(int* a, int start, int end) { 
    int f = start;//f是父结点位置
    int tmp = a[f];//先暂存要比较的父结点大小
    int c = 2 * f + 1;//左孩位置
    //构造大顶堆,左孩没有超出树的范围表明该分支还有下一层孩子结点需要判断
    while (c <= end) {
        if (c < end && a[c] < a[c + 1])  c++; //如果有右孩,则用较大的孩子与父结点进行比较         
        //如果父结点小于孩子结点,则互换两结点的值
        if (tmp < a[c]) {
            a[f] = a[c];
            a[c] = tmp;
            f = c;//以原孩子结点编号作为新的父结点编号,检查该分支是否还有下一层孩子结点需判断
            c = 2 * f + 1;//求新的左孩结点编号
        }
        else break; //如果父结点不小于孩子结点,此时已是大顶堆,不需要再向下判断,可提前结束while循环              
    }
    return;
}

//堆排序(升序排序)
void HeapSortUp(int a[], int n) {
    int i, tmp;
    //初始化大顶堆不需要考虑元素是否已被取出排序  
    for (i = n / 2 - 1; i >= 0; i--) {
        MaxHeap(a, i, n - 1); 
    }           

    //将根结点a[0](最大值)放到序列最后(升序排序)
    for (i = n - 1; i > 0; i--)
    {
        tmp = a[0];//将根结点a[0]与最后一个结点a[i]互换
        a[0] = a[i];
        a[i] = tmp;
        //重新构造大顶堆需要考虑元素是否已被取出排序
        //start为序列第一个未排序元素a[0],end为最后一个未排序元素a[i-1]
        MaxHeap(a, 0, i - 1);
    }
    return;
}

int main(){
    int i;
    int a[] = { 20,30,90,40,70,60,110,10,100,50,80 };
    int n = (sizeof(a)) / (sizeof(a[0]));
    cout << "序列个数:" << n << endl;
    cout << "排序前:";
    for (int i = 0; i < n; i++)
        cout << a[i] << " ";
    cout << endl;

    HeapSortUp(a, n);

    cout << "排序后:";
    for (int i = 0; i < n; i++)
        cout << a[i] << " ";
    cout << endl;
    return 0;
}

posted @ 2022-09-25 22:33  zhaoo_o  阅读(1)  评论(0编辑  收藏  举报