堆排序(Heap Sort)只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。

(1)基本概念a)堆:设有n个元素的序列:

{k1, k2, ..., kn}

对所有的i=1,2,...,(int)(n/2),当满足下面关系:

ki≤k2i,ki≤k2i+1

或            ki≥k2i,ki≥k2i+1

这样的序列称为堆。

堆的两种类型:根结点最小的堆----小根堆。

根结点最大的堆----大根堆。根结点称为堆顶,即:在一棵完全二叉树中,所有非叶结点的值均小于(或均大于)左、右孩子的值。

b)堆排序:是一种树型选择排序,特点是,在排序过程中,把R[1..n]看成是一个完全二叉树的存储结构,利用完全二叉树双亲结点和孩子结点的内在关系,在当前无序区中选择关键字最大(最小)的记录。

2)堆排序步骤:1、从k-1层的最右非叶结点开始,使关键字值大(或小)的记录逐步向二叉树的上层移动,最大(或小)关键字记录成为树的根结点,使其成为堆。

2、逐步输出根结点,令r[1]=r[i](i=n,,n-1,...,2),在将剩余结点调整成堆。直到输出所有结点。我们称这个自堆顶到叶子的调整过程为“筛选”。

(3)要解决的两个问题:1、如何由一个无序序列建成一个堆;

2、输出一个根结点后,如何将剩余元素调整成一个堆。

将一个无序序列建成一个堆是一个反复“筛选”的过程。若将此序列看成是一个完全二叉树,则最后一个非终端结点是第floor(n/2)个元素,由此“筛选”只需从第floor(n/2)个元素开始。

堆排序中需一个记录大小的辅助空间,每个待排的记录仅占有一个存储空间。堆排序方法当记录较少时,不值得提倡。当n很大时,效率很高。堆排序是不稳定的。

堆排序的算法和筛选的算法如第二节所示。为使排序结果是非递减有序排列,我们在排序算法中先建一个“大顶堆”,即先选得一个关键字为最大的记录并与序列中最后一个记录交换,然后对序列中前n-1个记录进行筛选,重新将它调整为一个“大顶堆”,然后将选得的一个关键字为最大的记录(也就是第一个元素)与当前最后一个记录交换(全局看是第n-1个),如此往复,直到排序结束。由到,筛选应按关键字较大的孩子结点向下进行。

堆排序的算法描述如下:

用C语言代码实现如下:

复制代码 代码如下:

#include "iostream"

using namespace std;

#define MAXSIZE 20

typedef struct

{

int key;

//其他数据信息

}RedType;

typedef struct

{

RedType r[MAXSIZE+1];

int length;

}Sqlist;

typedef Sqlist HeapType;  //堆采用顺序表存储表示

void HeapAdjust(HeapType &H,int s,int m)   //已知H.r[s...m]中记录的关键字出H.r[s].key之外均满足堆的定义,本函数调整H.r[s]的关键字,使H.r[s...m]成为一个大顶堆(对其中记录的关键字而言)

{

int j;

RedType rc;

rc=H.r[s];

for(j=2*s;j<=m;j*=2)   //沿key较大的孩子结点向下筛选

{

if(j

++j;

if(rc.key>=H.r[j].key)           //rc应插入在位置s上

break;

H.r[s]=H.r[j];      //将左、右孩子较大的结点与父节点进行交换,建成大顶堆

s=j;

}

H.r[s]=rc;             //插入

}

void HeapSort(HeapType &H)      //对顺序表H进行堆排序

{

int i;

for(i=H.length/2;i>0;--i)   //由一个无序序列建成一个大顶堆,将序列看成是一个完全二叉树,则最后一个非终端节点是第n/2个元素

HeapAdjust(H,i,H.length);

for(i=H.length;i>1;--i)

{

H.r[0]=H.r[1];   //将堆顶记录和当前未经排序的子序列H.r[1...i]中最后一个记录相互交换

H.r[1]=H.r[i];

H.r[i]=H.r[0];

HeapAdjust(H,1,i-1);    //将H.r[1...i-1]重新调整为大顶堆

}

}//HeapSort

void InputL(Sqlist &L)

{

int i;

printf("Please input the length:");

scanf("%d",&L.length);

printf("Please input the data needed to sort:\n");

for(i=1;i<=L.length;i++)    //从数组的第1个下标开始存储,第0个下标作为一个用于交换的临时变量

scanf("%d",&L.r[i].key);

}

void OutputL(Sqlist &L)

{

int i;

printf("The data after sorting is:\n");

for(i=1;i<=L.length;i++)

printf("%d ",L.r[i].key);

printf("\n");

}

int main(void)

{

Sqlist H;

InputL(H);

HeapSort(H);

OutputL(H);

system("pause");

return 0;

}

不使用上面的结构体的另外一种方法如下:

复制代码 代码如下:

/*

*堆排序

*/

#include "iostream"

using namespace std;

#define N 10

int array[N];

void man_input(int *array)

{

int i;

for(i=1;i<=N;i++)

{

printf("array[%d]=",i);

scanf("%d",&array[i]);

}

}

void mySwap(int *a,int *b)//交换

{

int temp;

temp=*a;

*a=*b;

*b=temp;

}

void heap_adjust(int *heap,int root,int len)     //对堆进行调整,使下标从root到len的无序序列成为一个大顶堆

{

int i=2*root;

int t=heap[root];

while(i<=len)

{

if(i

{

if(heap[i]

i++;

}

if(t>=heap[i])

break;

heap[i/2]=heap[i];

i=2*i;

}

heap[i/2]=t;

}

void heapSort(int *heap,int len)      //堆排序

{

int i;

for(i=len/2;i>0;i--)    //由一个无序序列建成一个大顶堆,将序列看成是一个完全二叉树,则最后一个非终端节点是第len/2个元素

{

heap_adjust(heap,i,len);

}

for(i=len;i>=1;i--)

{

mySwap(heap+i,heap+1);    //将堆顶记录与最后一个记录相互交换

heap_adjust(heap,1,i-1);   //将下标为1~i-1的记录重新调整为大顶堆

}

}

void print_array(int *array,int n)

{

int k;

for(k=1;k

{

printf("%d\t",array[k]);

}

}

int main(void)

{

man_input(array);

heapSort(array,N);

printf("\nAfter sorted by the heap_sort algorithm:\n");

print_array(array,N);   //打印堆排序结果

system("pause");

return 0;

}

c语言内部堆排序的实现,内部排序之堆排序的实现详解相关推荐

  1. python实现排序函数_Python排序函数的使用方法详解

    Python排序函数完美体现了Python语言的简洁性,对于List对象,我们可以直接调用sort()函数(这里称为"方法"更合适)来进行排序,而对于其他可迭代对象(如set,di ...

  2. 20191007:选择排序,插入排序,冒泡排序详解

    选择排序,插入排序,冒泡排序详解 描述 图例 代码实现 描述 选择排序:将要排序的对象分作两部份,一个是已排序的,一个是未排序的,从后端未排序部份选择一个最小值,并放入前端已排序部份的最后一个. 插入 ...

  3. 多图上传以及多图排序的方法及流程详解

    多图上传以及多图排序的方法及流程详解 ps:本人亲测,阿里云2核4G5M的服务器性价比很高,新用户一块多一天,老用户三块多一天,最高可以买三年,感兴趣的可以戳一下:阿里云折扣服务器 所用插件包打包下载 ...

  4. c语言程序关键字是什么,C语言中32个关键字详解

    C语言中32个关键字详解 由 ANSI 标准定义的 C 语言关键字共32个,根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类. 一.数据类型关键字 A 基本数据类型(5个) vo ...

  5. 八大排序算法——(万字图文详解)

    本篇文章是我对之前写过的八个排序算法的总结,感兴趣的小伙伴可以去我的八大排序算法专栏浏览,也可以点击下方标题跳转. 提示:本篇博客篇幅较长,建议小伙伴们查看目录,按需浏览 目录 正文 1 直接插入排序 ...

  6. 单片机推挽输出c语言,单片机IO口科普:推挽输出、开漏输出详解

    原标题:单片机IO口科普:推挽输出.开漏输出详解 在学单片机和选用逻辑器件的时候我们常别人说这款芯片是推挽输出驱动能力强,这个引脚是开漏输出需要加上拉电阻. 是不是有时候感觉一头雾水? 今天就详解一下 ...

  7. 使用order by排序判断返回结果的列数,order by排序判断字段数原理详解

    「作者主页」:士别三日wyx order by排序猜解列数原理详解 一.order by的两种使用方式 1)按照字段名排序 2)按照索引排序 二.order by怎么判断字段数? 1)正常的排序 3) ...

  8. 在C语言中实现协程库(一)----------协程切换原理详解

    从这篇文章开始,我将一点一点详细介绍如何在c语言中实现协程库.并对其中涉及到的技术进行详细的解释. 感兴趣的小伙伴欢迎一起参与 代码地址 协程切换原理 使用glibc中<ucontext.h&g ...

  9. c语言 多线程 传话,code vs1506传话(塔尖)+tarjan图文详解

    1506 传话 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 一个朋友网络,如果a认识b,那么如果a第一次收到某个消息,那么会 ...

  10. 【算法】桶排序(Bucket Sort)详解

    1. 概述 桶排序(Bucket Sort)又称箱排序,是一种比较常用的排序算法.其算法原理是将数组分到有限数量的桶里,再对每个桶分别排好序(可以是递归使用桶排序,也可以是使用其他排序算法将每个桶分别 ...

最新文章

  1. [C#基础]Func和Action学习
  2. 借“样式”巧用Word自带的多级项目符号!
  3. redis哨兵机制在集群中的应用
  4. Javascript DOM动态添加表格
  5. vue输入框联想词功能
  6. boost::ratio_multiply相关的测试程序
  7. php 中数组的定义赋值吗,怎么在php中定义一个数组
  8. 什么是前端开发中的Pseudo elements
  9. Android实现点击两次返回键退出
  10. 找零钱--C语言实现
  11. mysql主祝福hi_MySql - GROUP BY 和 HAVING关键字
  12. mysql主从复制不同步案例_mysql主从复制不同步的问题
  13. JAVA-JDK环境变量配置
  14. 哼唱也能识别歌名 音乐APP听歌识曲谁家强
  15. RocketMQ事务消息学习及刨坑过程
  16. linux 深信服ssl_深信服ssl
  17. android自定义View之气球碰撞效果
  18. 通过CE寻找内存基址
  19. hdu 1024 Max Sum Plus Plus(dp 最大m子段和)
  20. mysql sql查询时区_MySQL查看和修改时区的方法

热门文章

  1. 【英语学习】【Level 07】U05 Best Destination L2 The City of Lights
  2. Intel 64/x86_64/IA-32/x86处理器 - 锁原子操作(1) - 处理器保证的原子操作
  3. Pentium II Pentium III架构/微架构/流水线 (1) - 架构概述
  4. java导出excel 客户端_Java poi导出Excel下载到客户端
  5. 球谐函数的概念与应用:可视化理解傅里叶级数
  6. 未来属于SVO? - KlayGE游戏引擎
  7. OpenGL ES 2.0 Shader相关介绍
  8. TensorFlow-RNN循环神经网络 Example 2:文本情感分析
  9. Go语言标准库之strconv
  10. 7.Appium 安卓自动化(Package与Activity)