数据结构_堆排序介绍

原文作者:http://www.cnblogs.com/skywang12345/p/3602162.html。在他基础上修改了一点

堆排序介绍

堆排序(Heap Sort)是指利用堆这种数据结构所设计的一种排序算法。
因此,学习堆排序之前,有必要了解堆!若读者不熟悉堆,建议先了解(建议可以通过二叉堆左倾堆斜堆二项堆斐波那契堆等文章进行了解),然后再来学习本章。

我们知道,堆分为"最大堆"和"最小堆"。最大堆通常被用来进行"升序"排序,而最小堆通常被用来进行"降序"排序。
鉴于最大堆和最小堆是对称关系,理解其中一种即可。本文将对最大堆实现的升序排序进行详细说明。

最大堆进行升序排序的基本思想:
① 初始化堆:将数列a[1...n]构造成最大堆。
② 交换数据:将a[1]和a[n]交换,使a[n]是a[1...n]中的最大值;然后将a[1...n-1]重新调整为最大堆。 接着,将a[1]和a[n-1]交换,使a[n-1]是a[1...n-1]中的最大值;然后将a[1...n-2]重新调整为最大值。 依次类推,直到整个数列都是有序的。

下面,通过图文来解析堆排序的实现过程。注意实现中用到了"数组实现的二叉堆的性质"。
在第一个元素的索引为 0 的情形中:
性质一:索引为i的左孩子的索引是 (2*i+1);
性质二:索引为i的左孩子的索引是 (2*i+2);
性质三:索引为i的父结点的索引是 floor((i-1)/2);

堆排序个人总结:

第一步 构建堆的向下调整算法 一个for循环从n/2开始减减;
第二步 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
heap_sort_asc(a, n)的作用是:对数组a进行升序排序;其中,a是数组,n是数组长度。操作分为两部分:初始化堆 和 交换数据。=两个for循环maxheap_down(a, start, end)是最大堆的向下调整算法。=一个for循环,几个if-else
#include <stdio.h>

// 数组长度
#define LENGTH(array) ( (sizeof(array)) / (sizeof(array[0])) )
#define swap(a,b) (a^=b,b^=a,a^=b)

/*
 * (最大)堆的向下调整算法
 *
 * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 *     其中,N为数组下标索引值,如数组中第1个数对应的N为0。
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     start -- 被下调节点的起始位置(一般为0,表示从第1个开始)
 *     end   -- 截至范围(一般为数组中最后一个元素的索引)
 */
void maxheap_down(int a[], int start, int end)
{
    int start1 = start ;         // start 当前(current)节点的位置
    int position = 2*start1 + 1; // 左(left)孩子的位置
    int tmp = a[start1];         // 当前(current)节点的大小
    for( ;position<=end ; )
    {
        if(position<end&&a[position]<a[position+1])
            position++;
        if(a[position]<=tmp)
            break;
        else//交换
        {
            a[start1]=a[position];  //将较大值上移
            a[position]=tmp;       //同时将tmp下移
        }
        start1=position  ;           //同时start1变为新的
        position=2*position+1;      //左孩子也变化
    }

}

/*
 * 堆排序(从小到大)
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     n -- 数组的长度
 */
void heap_sort_asc(int a[], int n)
{
    int i;
    //第一步 构建堆的向下调整算法
    for(i=n/2;i>=0;i--)
    {
        maxheap_down(a,i,n-1); // 第一步一直执行完所有的
    }
    //第二步 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
    for(i=n-1;i>0;i--)
    {
        swap(a[0],a[i]);        // 交换一次,将最大值放在数组最后面的a[i];
        maxheap_down(a,0,i-1);  // 剔除一个最后面的数组元素重新构建堆
    }
}
void main()
{
    int i;
    int a[] = {20,30,90,40,70,110,60,10,100,50,80};
    int ilen = LENGTH(a);

    printf("before sort:");
    for (i=0; i<ilen; i++)
        printf("%d ", a[i]);
    printf("\n");

    heap_sort_asc(a, ilen);            // 升序排列
    //heap_sort_desc(a, ilen);        // 降序排列

    printf("after  sort:");
    for (i=0; i<ilen; i++)
        printf("%d ", a[i]);
    printf("\n");
}

时间: 2024-08-04 21:03:07

数据结构_堆排序介绍的相关文章

数据结构_课程设计——最小生成树:室内布线

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 这道课程设计,费不少时间,太麻烦了= =.(明明是能力不够) ~~~~最小生成树:室内布线~~~~ 题目要求: 装修新房子是一项颇为复杂的工程,现在需要写个程序帮助房主设计室内电线的布局. 首先,墙壁上插座的位置是固定的.插座间需要有电线相连,而且要布置的整齐美

数据结构_课程设计——并查集:检查网络

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 这两天做数据结构课程设计,因为以前做过ACM题,感觉还可以,不是很难呀 ~~~~并查集:检查网络~~~~ 题目要求: 给定一个计算机网络以及机器间的双向连线列表,每一条连线允许两端的计算机进行直接的文件传输,其他计算机间若存在一条连通路径,也可以进行间接的文件传

数据结构之堆排序

堆排序,是数据结构中重要的排序方法,可以很快帮你找到最大值.在实际应用中,如 最大优先级队列是大顶推的应用,可以很快找到优先级最高的队列. 1.堆概念 堆的定义如下,n个元素的序列{k1,k2,...kn},当且仅当满足如下关系: ki>=k2i               或者         ki<=k2i ki>=k2i+1                          ki<=k2i+1 分别对应大顶堆和小顶堆. 堆可以看作一个完全二叉树,所有非终端点都大于或都小于左右

中间件_百科介绍

中间件 编辑 中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源.中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯.是连接两个独立应用程序或独立系统的软件.相连接的系统,即使它们具有不同的接口,但通过中间件相互之间仍能交换信息.执行中间件的一个关键途径是信息传递.通过中间件,应用程序可以工作于多平台或 OS 环境. 目录 1基本概念 2相关概念 3基本特点 ? 特长? 局限 4发展沿革 ? CICS? 服务器? 发展现状 5分类 ? 远程过

Windows 已在 数据结构_顺序表.exe 中触发一个断点——new和delete注意事项

实现数据结构的顺序表的类时,输入,改,删,查都可以,但是最后析构函数时持续出错 错误提示"Windows 已在 数据结构_顺序表.exe 中触发一个断点" int *elem=new int(LIST_INIT_SIZE); if(!elem)cout<<"overflow"<<endl; if(leng>LIST_INIT_SIZE) cout<<"error"; else {    length=le

数据结构--优先队列(堆排序)

数据结构--优先队列(堆排序) 优先队列:不是先进先出啦,下面的代码是大顶堆,大的先出. 在之前理解堆排序的基础上,在来理解优先队列. 还是用这个公式: leftNo = parentNo*2+1 rightNo = parentNo*2+2 parentNo = (nodeNo-1)/2 每次进队列是从最后进,在慢慢上浮. 每次出队列,堆顶先出,在把队尾调到堆顶,在下浮. 上代码 package sy181002; import java.util.Arrays; /** * 优先队列 * *

数据结构:堆排序

「仅为草稿,尚未详解」 堆排序(C语言版) 走进堆排序 什么是堆 堆实质就是一颗完全二叉树,其任何一非叶子节点满足下列性质. i=1,2,3...n/2 说明: 既然是完全二叉树,我们就可以用数组来表示! 堆根据上面的性质又分为: 从中不难发现,大顶堆从上往下依次键值减小,小顶堆从上向下键值增大. 什么是堆排序 ? 对一组待排序记录的关键字,首先把它们按堆的定义建成小(大)顶堆 ? 然后输出堆顶的最小(大)关键字所代表的记录,再对剩余的关键字建堆,以便得到次小(大)的关键字 ? 如此反复进行,直

数据结构_概览

概念: 数据:是对客观事物的符号表示.能输入到计算机中并且被计算机程序处理的符号的总称: 数据元素:描述数据的基本单位: 数据项:描述数据的最小单位: 数据类型:数值,字符等对数据分成不同的类型: 抽象数据类型:由数据对象,数据关系和基本操作三部分组成,可用三元组(D,S,P)表示: 数据结构:数据和结构两部分,数据部分是数据元素的集合,结构是指数据之间关系的集合: 数据结构的逻辑结构:用抽象的数据模型来描述数据结构中数据元素之间的逻辑关系: 物理结构(又叫 存储结构 或者 内存映像):数据在计

数据结构与算法 介绍以及常见的算法排序

介绍 数据结构: 计算机存储,组织数据的结构.指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成. 线性数据结构:数组,链表 应用:队列 栈 非线性数据结构:树,图 算法: 对数据结构中数据的操作 常见的算法排序 low B三件套 #冒泡排序 #时间复杂度:O(n2) #空间复杂度:O(1) def bubble_sort(li): for i in range(len(li)-1): flag = False for j in range(len(li)-i-1):