堆排序

来源:互联网 发布:台达plc编程入门 编辑:程序博客网 时间:2024/06/02 04:00

排序有很多种方法,堆排序是其中的一种。它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。

堆有一个很好的性质:第i个位置上的值小于第2*i个位置上和第2*i+1个位置上的值(i<2*i && i<2*i+1),这种堆称为小根堆;第i个位置上的值大于第2*i个位置上和第2*i+1个位置上的值(i<2*i && i<2*i+1),这种堆称为大根堆。而第i个位置正好是第2*i个位置和2*i+1个位置的父母结点。

小根堆排序后是从大到小,大根堆排序后是从小到大。

我们先把准备工作做好

#include <stdio.h>#include <stdlib.h>#include<math.h>#define MAX_SIZE 100typedef char InfoType;typedef struct Sz{    int key;    InfoType *info;}Sz;typedef struct SQ//定义一个顺序线性表{    Sz *R;    int length;}SqList;int Init_SqList(SqList *L)//顺序线性表初始化{    L->R=(Sz *)malloc((MAX_SIZE + 1) * sizeof(Sz)) ;    if(!L->R)        return 0;    else    {        L->length = 0;        return 1;    }}

要对一个数组进行堆排序,首先要建立一个堆。

void Heap_adjust(SqList *L, int s, int m){    /*H->R[s…m]中记录关键字除H->R[s].key均满足堆定义*/    /*调整H->R[s]的位置使之成为小根堆*/    int j = s;//起始位置    int k = 2 * j;/*计算H->R[j]的左孩子的位置*/    L->R[0] = L->R[j];/*临时保存H->R[j]*/    for (k = 2 * j; k <= m; )//k = 2*k    {        if(((k + 1) <= m) && (L->R[k].key > L->R[k + 1].key))            k++;/*选择左、右孩子中关键字的最的一个*/        if(L->R[k].key < L->R[0].key)        {            L->R[j] = L->R[k];            j = k;            k = 2 * j;        }        else        {            break;        }    }    L->R[j] = L->R[0];}

然后把第一个元素和最后一个元素交换,交换之后可能就把堆打乱了,所以要重新在建立一个堆。这样交换n-1次,数组就有序了。

void Heap_Sort(SqList *L){    int i;    int j;    for(j = L->length/2; j > 0; j--)        Heap_adjust(L, j, L->length);/*初始建堆*/    for(j = 1; j <= L->length; j++)    {        printf("%d  ", L->R[j].key);    }    printf("\n");    printf("------------------------------\n");    int k = L->length;    //需要进行n-1次交换    for(j = k; j > 1; j--)    {        L->R[0] = L->R[1];        L->R[1] = L->R[k];        L->R[k] = L->R[0];/*堆顶与最后一个交换*/        k--;/*每交换一次,长度减一,把最后一个元素除去*/        printf("%d\n", k);        if(j != 1)        {            for(i = ceil(k / 2); i > 0; i--)                Heap_adjust(L, i, k);/*建堆*/        }        for(i = 1; i <= k; i++)        {            printf("%d  ", L->R[i].key);        }        printf("\n");    }}

主方法

int main(){    int i;    int num;    SqList L;    Init_SqList(&L);    /*输入数组*/    printf("please enter the number of the data:");    scanf("%d", &num);    for(i = 1; i < num + 1; i++){        int values;        printf("please enter the %d data:", i);        scanf("%d", &values);        L.R[i].key = values;        L.length++;    }    for(i = 1; i <= L.length; i++)    {        printf("%d  ", L.R[i].key);    }    printf("\n");    printf("-------------create heap----------------\n");    Heap_Sort(&L);    printf("-------------after heap sort----------------\n");    for(i = 1; i <= L.length; i++)    {        printf("%d  ", L.R[i].key);    }    printf("\n");    return 0;}

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

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 仙网 莆仙网论坛 仙武帝尊飞速中文网 仙武帝尊txt下载奇书网 软萌网红小仙vip 网红软萌萝莉小仙猫耳 软萌网红小仙水手服 叶辰仙武帝尊飞速中文网 仙帝归来猎文网 玩网仙气圈名 网红沙滩仙本那堆满垃圾 仙帝归来云青岩txt下载包书网 艳鼎丹仙txt下载奇书网 ss8009倾听网小仙儿 仙网管理员 陌上等你v 我修的是假仙txt下书网 尤果网仙妮 逸仙中大考研网 飘飘仙狼太郎txt下载出包网 仙葫txt下载奇书网 仙武帝尊八一中文网 仙帝归来txt下书网 仙网txt全集下载 仙网全文阅读 御宅书屋自由阅读网仙娈 仙股 仙坛股份千股千评 股仙 仙股是什么意思 仙矛 仙芧的功效与作用 仙毛的功效与作用 仙茅 仙茅图片 独脚仙茅 茅仙酒 仙茅不适合哪种人群吃 绒叶仙茅 大叶仙茅 仙茅的功效与作用 茅仙酒价格