ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【排序】堆排序

2022-01-06 16:31:01  阅读:151  来源: 互联网

标签:arr int void 堆排序 length HeapAdjust SqList 排序


堆排序

1.代码模板

void HeapSort(SqList *L);  // 堆排序
void HeapAdjust(SqList *L, int s, int m);   // 堆调整 将L->arr[s...m]调整成一个大顶堆

void HeapSort(SqList *L)
{
    // 从下到上,从右到左,把L中的arr构建成一个大顶堆
    for (int i = L->length / 2; i > 0; i -- )  
        HeapAdjust(L, i, L->length);
    // 正式的排序过程
    for (int i = L->length; i > 1; i -- ) {
        swap(L, 1, i);  // 将堆顶元素和当前未经排序子序列的最后一个元素交换
        HeapAdjust(L, 1, i - 1);  // 将L->arr[1...i-1]重新调整为大顶堆
    }
}

void HeapAdjust(SqList *L, int s, int m)
{
    int temp = L->arr[s];
    // 
    for (int j = 2 * s; j <= m; j *= 2) {   // j为s的左孩子,j+1为s的右孩子
        if (j < m && L->arr[j] < L->arr[j+1])  // j不是最后一个结点,且左孩子小于右孩子
            ++j;
        if (temp >= L->arr[j])
            break;
        L->arr[s] = L->arr[j]; // 将该二叉树的最大值赋给根节点
        s = j;  // s指向原最大值的位置
    }
    L->arr[s] = temp;   // 插入
}

2.算法介绍

堆排序是对简单选择排血的一种改进,也属于选择类排序。做出的改进思想是:简单选择排序中,在含有n个元素的序列中找到最小的元素需要比较n-1次,但这一趟的其他比较结果并没有被保存下来,我们只选出了最小值,在下一次比较时,有许多比较其实已经被做过了,但由于前一趟没有保存下来,所以这些比较操作在这一趟的比较中又被重复执行了,导致排序的总比较次数较多。

堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;每个结点的值都小于或等于其左右孩子的值,称为小顶堆。

堆排序算法是一种利用大顶堆或小顶堆结构进行排序的算法,其算法思想是:先将待排的序列从下到上、从右到左地构造成一个大顶堆,此时整个序列的最大值就是堆顶的根节点,把根节点移走,将堆数组的末尾元素(即序列的最小值)当做新的根结点,将其重新调整为一个大顶堆,注意此时被移走的原根结点不参与排序,然后反复执行移走跟结点再重新调整的操作,这样被移走的元素就构成了一个有序的序列。

补充:在一颗完全二叉树中,若当前结点的序号是s,则其左孩子的序号一定为2s,右孩子的序号一定为2s+1,孩子的孩子也是以2为倍数增加。

3.实例

#include <iostream>
using namespace std;

const int N = 100;

typedef struct
{
    int arr[N];
    int length;
} SqList;

void swap(SqList *L, int i, int j)
{
    int temp = L->arr[i];
    L->arr[i] = L->arr[j];
    L->arr[j] = temp;
}

void HeapSort(SqList *L);
void HeapAdjust(SqList *L, int s, int m);


void HeapSort(SqList *L)
{
    for (int i = L->length / 2; i > 0; i -- )   // 构造大顶堆
        HeapAdjust(L, i, L->length);

    for (int i = L->length; i > 0; i -- ) {
        swap(L, 1, i);
        HeapAdjust(L, 1, i - 1);
    }
}

void HeapAdjust(SqList *L, int s, int m) 
{
    int temp = L->arr[s];
    for (int j = 2 * s; j <= m; j *= 2) {
        if (j < m && L->arr[j] < L->arr[j+1])
            ++j;
        if (temp >= L->arr[j])
            break;
        L->arr[s] = L->arr[j];
        s = j;
    }
    L->arr[s] = temp;
}

int main()
{
    SqList L;
    L.arr[1] = 50;
    L.arr[2] = 10;
    L.arr[3] = 90;
    L.arr[4] = 30;
    L.arr[5] = 70;
    L.arr[6] = 40;
    L.arr[7] = 80;
    L.arr[8] = 60;
    L.arr[9] = 20;
    L.length = 9;

    HeapSort(&L);  // 堆排序测试
    for (int i = 1; i <= L.length; i ++ )
        cout << L.arr[i] << " ";

}

注:内容参考自《大话数据结构》

标签:arr,int,void,堆排序,length,HeapAdjust,SqList,排序
来源: https://blog.csdn.net/weixin_51424157/article/details/122346227

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有