/*
 * heapsort.cpp
 *
 *  Created on: 2016年3月30日
 *      Author: Lv_Lang
 */

//堆排序
#include <iostream>
using namespace std;

/*堆排序算法解析:
核心思想在于建立最大堆(或最小堆),
因为最大堆满足一个性质:所有的父节点都要比它的左右节点均要大,
于是据此可以每次将最大的(根节点)抽取出来(实际上是放最后面),
每次都抽取剩余部分的最大值,那最终得到的序列就是有序的。
所以堆排序其实算是一种高级版的选择排序。
建立最大堆的方法:首先从底层的父节点开始,把它的子树整成最大堆,
然后往上整成最大堆,注意这里要从下往上。
最后堆排序就是先建立一个最大堆,然后把根节点元素也就是最大的元素
跟最后面的元素交换,这样一来,树就未必满足最大堆了,所以要重新
进行堆的调整(不包括已经被抽取的最大元素)。这样下来,每次都抽取
出子序列的最大元素,最终的序列就从小到大排好序了。*/

void swap(int a[],int i,int j)
{
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}

void HeapAdjust(int *a,int i,int size)
{
	int left = 2*i;//左孩子节点
	int right = 2*i + 1;//右孩子节点
	int max = i;//暂存最大元素下标
	if(left <= size && a[left] > a[max])
		//这里不直接交换是因为如果交换则要进行递归,
		//所以连同右边的也判断了再做可能的交换和做可能的递归,
		//递归的原因则是因为你把人的老爸交换了,
		//那人家的儿子可能就比继父要大了。
		//swap(a,left,i);
		max = left;
	if(right <= size && a[right] > a[max])
		max = right;
	if(max != i)//表明当前的父节点并不是最大的
	{
		swap(a,i,max);
		HeapAdjust(a,max,size);//有交换就要递归把子树也整成最大堆
	}
}

void BuildHeap(int a[],int size)
{
	for(int i = size / 2;i >= 1;i--)//非叶节点最大下标为/2
	{
		HeapAdjust(a,i,size);
	}
}

//堆排序对要排序的序列有个要求就是下标是从1开始到size的,而并非常用的0~size-1
void HeapSort(int a[],int size)
{
	BuildHeap(a,size);//先建立初始的最大堆
	for(int i = size;i >= 2;i--)
	{
		swap(a,1,i);//把最大的元素放到最后面
		size--;//不再包括最大的元素
		//这里之所以直接从根节点开始维护堆是因为除了根节点外的其他子树都是最大堆了。
		//而上面第一次建立最大堆时不能保证父节点已经是最大的了,
		//所以上面的需要先从底层的非叶节点层开始维护/调整堆。
		HeapAdjust(a,1,size);
	}
	//至此数组就已经从小到大排好序了,
	//如果要从大到小输出,则倒着输出就行了;
	//而如果要将序列从大到小排序,则应建立最小堆。
}

void print(int a[],int size)
{
	for(int i=1;i < size;i++)
		cout<<a[i]<<" ";
	cout<<a[size]<<endl;
}

int main()
{
	int a[7] = {0,4,6,1,5,3,2};
	cout<<"排序之前的序列为:"<<endl;
	print(a,6);
	HeapSort(a,6);
	cout<<"排序之后的序列为:"<<endl;
	print(a,6);

	return 0;
}

关于堆排序算法,网上有更好更详细的解析,这里放一个我觉得挺好的解析博客,因为它有图:

点击打开链接

堆排序C++实现的更多相关文章

  1. 算法与数据结构(十四) 堆排序 (Swift 3.0版)

    上篇博客主要讲了冒泡排序.插入排序.希尔排序以及选择排序.本篇博客就来讲一下堆排序(Heap Sort).看到堆排序这个名字我们就应该知道这种排序方式的特点,就是利用堆来讲我们的序列进行排序.&quo ...

  2. [数据结构]——堆(Heap)、堆排序和TopK

    堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...

  3. 堆排序与优先队列——算法导论(7)

    1. 预备知识 (1) 基本概念     如图,(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树.树中的每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且从左向右填充.堆的数组 ...

  4. 数据结构:堆排序 (python版) 小顶堆实现从大到小排序 | 大顶堆实现从小到大排序

    #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Author: Minion-Xu 小堆序实现从大到小排序,大堆序实现从小到大排序 重点的地方:小堆序 ...

  5. 堆排序(python实现)

    堆排序是利用最大最或最小堆,废话不多说: 先给出几个概念: 二叉树:二叉树是每个节点最多有两个子树的树结构.通常子树被称作“左子树”(left subtree)和“右子树” 完全二叉树:除最后一层外, ...

  6. 堆排序分析及php实现

    堆排序:是一种特殊形式的选择排序,他是简单选择排序的一种改进. 什么是堆? 具有n个元素的序列:{k1,k2,ki,…,kn} (ki <= k2i,ki <= k2i+1) 或者 (ki ...

  7. 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析之后续补充说明(有图有真相)

    如果你觉得我的有些话有点唐突,你不理解可以想看看前一篇<C++之冒泡排序.希尔排序.快速排序.插入排序.堆排序.基数排序性能对比分析>. 这几天闲着没事就写了一篇<C++之冒泡排序. ...

  8. [Unity][Heap sort]用Unity动态演示堆排序的过程(How Heap Sort Works)

    [Unity][Heap sort]用Unity动态演示堆排序的过程 How Heap Sort Works 最近做了一个用Unity3D动态演示堆排序过程的程序. I've made this ap ...

  9. PHP实现堆排序

    经验 工作了,面试我工作这家公司时被技术面打击得不行,因为自己的数据结构等基础学得实在太差,虽然原来是想做设计师的说...不过看在PHP写得还凑合的份上能来实习了,但还是决心恶补一下基础. 其实自己之 ...

  10. 堆排序 Heapsort

    Prime + Heap 简直神了 时间优化好多,顺便就把Heapsort给撸了一发 具体看图 Heapsort利用完全二叉树+大(小)顶锥的结构每次将锥定元素和锥最末尾的元素交换 同时大(小)顶锥元 ...

随机推荐

  1. null

    期末考备考最后三天. 加油,把这学期学的知识给它搞透了.

  2. windows下安装beautifulsoup4

    方法一: pip install beautifulsoup4 方法二: 在官网下载安装包后,放在python目录下--运行cmd--进入bs4安装包路径--输入setup.py install 测试 ...

  3. JavaScript中的splice方法

    splice方法根据传入的不同参数可分别实现删除和插入操作 使用splice(pra1,pra2,pra3)方法,需要为其提供如下参数: 1.pra1为其起始索引(即希望开始添加元素的地方) 2.pr ...

  4. volatile关键字及编译器指令乱序总结

    本文简单介绍volatile关键字的使用,进而引出编译期间内存乱序的问题,并介绍了有效防止编译器内存乱序所带来的问题的解决方法,文中简单提了下CPU指令乱序的现象,但并没有深入讨论. 以下是我搭建的博 ...

  5. 配置MAVEN出现错误:java_home not found in your enviroment

    配置好maven后检测是否配置成功出现错误:java_home not found in your enviroment 找问题: 1.cmd--> path  看路径是否正确 2.cmd--& ...

  6. 【转】如何保护自己的QQ号

    账号丢失的原因 账号被注销 长时间未登陆 如果你的QQ号是普通号码,在连续三个月不登陆的情况下,腾讯公司会自动收回你的账号,也就意味着这个QQ号码从此再也不属于你了,会员号码是不会被收回的,要想不被收 ...

  7. cocoapod集成失败,无法找到头文件的解决办法

    在终端更新pod的时候,提示警告: target overrides the `OTHER_LDFLAGS` build setting defined in `Pods/Target Support ...

  8. mysql取前几行数据limit用法

    转自http://www.cnblogs.com/study100/archive/2013/07/30/3224250.html 在mysql中是没有top关键字的,在mysql中可以用limit来 ...

  9. Windows Store App 全球化 设置指定页面的语言

    上一小节介绍了通过在应用程序中添加语言设置选项来改变整个应用显示信息的语言,而有时用户只想对应用中某一页面信息的语言进行调整,这时就不能使用上一小节所讲述的知识来对应用进行设置.下面将通过一个示例介绍 ...

  10. ExtJs 之 ComboBox级联使用

    刚接触ExtJs不到一周,项目使用ExtJs框架,有个版块用到了combobox的级联(两级),遇到了一系列的问题,两天来一直查API.网络资料,终于解决了. 先列出遇到的一系列问题(也许你也遇到过! ...