堆排序

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

最小堆和最大堆如下图示:

可以发现:根结点一定是堆中所有结点最大(小)者。

堆排序的基本思想(以大顶堆为例):将待排序的序列构成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的 n-1 个序列重新构成一个堆,这样就会得到 n 个元素中的次大值。如此反复执行,便能得到一个有序序列了。

堆排序的思想用例图解释如下:

1. 初始最小堆的建立过程(自下向上逐步调整为最小堆)

具体代码如下:

1、排序前的一些准备工作,建立合适的排序需要的结构。

/********* 排序用到的结构  头文件sort_struct.h ************/
#define MAXSIZE 100 //要排序数组个数最大值 class SqList{
public:
int r[MAXSIZE+1];
int length;
}; /* 交换L中数组r下标为i和j的值 */
void swap(SqList *L, int i, int j)
{
int temp = L->r[i];
L->r[i] = L->r[j];
L->r[j] = temp;
} /* 显示数组内容 */
void showSqList(SqList *L)
{
for(int i=1;i<=L->length;i++)
std::cout<<L->r[i]<<" ";
std::cout<<std::endl;
}

2、编写主文件,实现排序与测试。

/********* C++堆排序算法 ************/
#include<iostream>
#include<time.h>
#include"sort_struct.h"
using namespace std; /* 本函数调整L->r[s]的关键字,使L->r[s...m]成为一个大顶堆 */
void HeapAdjust(SqList *L,int s,int m)
{
int temp,j;
temp = L->r[s];
for(j=2*s;j<=m;j*=2) //沿关键字较大的孩子结点向下筛选
{
if(j<m && L->r[j]<L->r[j+1])
++j; //j为关键字中较大的孩子结点的下标
if(temp>=L->r[j]) //如果关键字均大于孩子结点,跳出
break;
L->r[s] = L->r[j]; //否则交换关键字与较大孩子结点的内容
s = j;
}
L->r[s] = temp; //完成插入
} /* 对顺序表L进行堆排序 */
void HeapSort(SqList *L)
{
int i;
for (i=L->length/2;i>0;i--) //把L中的r构建成一个大顶堆
HeapAdjust(L,i,L->length); for (i=L->length;i>1;i--)
{
swap(L,1,i); //将堆顶记录和当前未经排序子序列的最后一个记录交换
HeapAdjust(L,1,i-1); //将L->r[1...i-1]重新调整为大顶堆
}
} int main()
{
int num[] = {0,50,30,25,15,84,56,34,99,54,111,24,43,6,62,124};
SqList *L = new SqList;
L->length = sizeof(num)/sizeof(int)-1;
for(int i=1;i<=L->length;i++)
L->r[i] = num[i];
cout<<"排序前:";
showSqList(L);
clock_t start = clock();
HeapSort(L);
clock_t end = clock();
double time = ((double)(start-end)) / (double)CLOCKS_PER_SEC * 1000;
cout<<"排序后:";
showSqList(L);
cout<<"耗时:"<<time<<"ms"<<endl;
return 0;
}

运行结果如下:

由于待排序样本太少,耗时显示为0。

C++编程练习(13)----“排序算法 之 堆排序“的更多相关文章

  1. Java常见排序算法之堆排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  2. Java排序算法之堆排序

    堆的概念: 堆是一种完全二叉树,非叶子结点 i 要满足key[i]>key[i+1]&&key[i]>key[i+2](最大堆) 或者 key[i]<key[i+1] ...

  3. 排序算法之堆排序(Heapsort)解析

    一.堆排序的优缺点(pros and cons) (还是简单的说说这个,毕竟没有必要浪费时间去理解一个糟糕的的算法) 优点: 堆排序的效率与快排.归并相同,都达到了基于比较的排序算法效率的峰值(时间复 ...

  4. 《排序算法》——堆排序(大顶堆,小顶堆,Java)

    十大算法之堆排序: 堆的定义例如以下: n个元素的序列{k0,k1,...,ki,-,k(n-1)}当且仅当满足下关系时,称之为堆. " ki<=k2i,ki<=k2i+1;或k ...

  5. C++编程练习(16)----“排序算法 之 快速排序“

    快速排序 基本思想: 通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 算法介绍: 设要排序的 ...

  6. 数据结构与算法之PHP排序算法(堆排序)

    一.堆的定义 堆通常是一个可以被看做一棵树的数组对象,其任一非叶节点满足以下性质: 1)堆中某个节点的值总是不大于或不小于其父节点的值: 每个节点的值都大于或等于其左右子节点的值,称为大顶堆.即:ar ...

  7. 八大排序算法之七—堆排序(Heap Sort)

    堆排序是一种树形选择排序,是对直接选择排序的有效改进. 基本思想: 堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足 时称之为堆.由堆的定义可以看出,堆顶元素(即第一个元素) ...

  8. Python 一网打尽<排序算法>之堆排序算法中的树

    本文从树数据结构说到二叉堆数据结构,再使用二叉堆的有序性对无序数列排序. 1. 树 树是最基本的数据结构,可以用树映射现实世界中一对多的群体关系.如公司的组织结构.网页中标签之间的关系.操作系统中文件 ...

  9. C++编程练习(15)----“排序算法 之 归并排序“

    归并排序 归并排序(Merging Sort)的原理: 假设初始序列含有 n 个记录,则可以看成是 n 个有序的子序列,每个子序列的长度为1,然后两两归并,得到 [n/2] ([ x ] 表示不小于 ...

随机推荐

  1. Sping--自动装配(byname, bytype)

    UserDAOImpl.java: package com.bjsxt.dao.impl; import com.bjsxt.dao.UserDAO; import com.bjsxt.model.U ...

  2. OPENCV图像变换-2

    一.经典霍夫变换 霍夫变换是图像处理中的一种特征提取技术,该方法通过在一个参数空间中通过计算累计结果的局部最大值来得到一个符合该特定形状的集合,作为结果. 运用两个坐标空间之间的变换,将一个空间中具有 ...

  3. R Student Companion(R语言初学指南)的源代码_数据_插图

    下载内容见附件:http://files.cnblogs.com/files/ml-cv/data_And_R_script.zip.

  4. svn无法提交

    svn无法提交, 错误信息:Commit failed. svn: E200007: CHECKOUT can only be performed on a version resource... 解 ...

  5. 怎样编制excel序列目录

    怎样编制序列目录 原帖内容:http://www.excelpx.com/forum.php?mod=viewthread&tid=164190&extra=%26page%3D1&a ...

  6. wordpress-标签

    来源1:http://www.graphicrating.com/2009/01/18/my-wordpress-cheat-sheet/ 来源2:http://www.cnblogs.com/asq ...

  7. oracle系列--级联删除和级联更新

    必须声明:此博客转载于Oracle外键级联删除和级联更新http://www.2cto.com/database/201507/417496.html 鉴于此前收藏的精彩博客无料被删除了,很是痛心,所 ...

  8. eclipse中集成svn maven开发手册---创建提分支

    开发时,需要拉取分支进行修改等操作 右键项目,选择team->分支/标记 输入创建分支地址 注意: 1,创建分支路径时,最后一层文件名称为项目的名称 2,点击浏览按钮可能会出现无法选择,且ecl ...

  9. jfreechart图表汉字乱码问题解决方案

    系统工作迁移环境 linux centos 6.5 tomcat8 mysql5.6 系统部署上之后,所有的jfreechart图表上的汉字,全部乱码. 如图: 经分析: 1)数据库动态读出来的是正常 ...

  10. javascript中的元素包含判断

    在实际开发中,很多时候需要知道某个节点是不是另一个节点的后代.很多浏览器提供了contains方法,如: console.log(document.documentElement.contains(d ...