堆排序是合并排序和插入排序排序方法共同的长处。它的时间复杂度O(nlgn),这也是一个地方排序算法:在任何时候,外阵中拥有唯一不变的输入数组存储的元素。引进第一家引进什么样的堆堆。

1.建堆:堆数据结构是一种数组对象,它能够被视为一颗全然二叉树。例如以下图。

右边数组表示的堆能够用左边的全然二叉树来表示。当中若父节点相应数组下标为i。则其左孩子相应数组下标为2*i。右孩子为2*i+1。

详细代码例如以下:

void buildMaxHeap(int a[] , int heapSize){

for(int i = heapSize/2;i >= 1;--i)

max_heapify(a,i,heapSize); //本行代码调用max_heapify函数来保持最大堆性质,接下来会介绍到。heapSize为堆大小。

}

2.保持根堆性质:接下来介绍大根堆与小根堆的差别。

大根堆某个节点的值最多是和其父节点一样大。小根堆的组织刚好相反。在堆排序中我们使用的是大根堆。

为了保持大根堆的性质。我们如果从下标为i的数组元素開始。将其值与它的左孩子和右孩子相比較,找出最大值相应的下标largest,如果largest恰好与i相等。则说明节点i保持了最大堆性质。

否则交换下标为largest和i所相应的数组元素值,而且对下标为largest的元素继续进行“保持根堆性质”的操作。这么说可能有些太缺乏生动性,那么一起来看看这个过程吧:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVfc3VuOTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

能够看到图中节点值为4的节点的保持根堆性质过程。代码例如以下:

void max_heapify(int a[],int i,int heapSize){

int lindex = 2*i,rindex = 2*i + 1,largest = 0;

if(lindex <= heapSize && a[lindex-1] > a[i-1])//推断左孩子和节点i的值谁大。将大值得下标保存为largest

largest = lindex;

else

largest = i;



if(rindex <= heapSize && a[rindex-1] > a[largest-1])//推断右孩子和节点largest的值谁大

largest = rindex;



if(largest != i){//假设largest不等于i

swap(a[i-1] , a[largest-1]);//交换

max_heapify(a,largest,heapSize);//继续对下标为largest、大小为heapSize的节点进行“保持根堆性质”

}

}

下面是swap函数:

void swap(int& first , int& second){

int tem = 0;

tem = first;

first = second;

second = tem;

}

3.堆排序算法:我用一个图来直观表示吧!

过程大致是将大根堆的根节点与最后一个叶子节点交换,然后缩小数组范围(即将heapSize减小),将最大值排除掉,最后对新的根节点进行“保持堆性质方法”。依次类推,代码例如以下:

void heapSort(int a[] , int heapSize){

buildMaxHeap(a , heapSize);//建堆

for(int i = heapSize;i >= 2;--i){

swap(a[0] , a[i-1]);//将根节点与最后的叶子节点交换

--heapSize;//缩小堆范围

max_heapify(a,1,heapSize);//保持堆性质



}

}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

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. g++优化选项

    g++优化选项 g++优化选项 对于下面的这段代码: 1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std; ...

  2. C++学习笔记10-面向对象

    1.  面向对象的程序设计是基于三个基本概念:数据抽象.继承和动态绑定. 在C++ 在,凭借一流的数据抽象,随着一类从一个类派生还继承:派生类的成员继承基类.决定是使用基类中定义的函数还是派生类中定义 ...

  3. pinyin4j的使用

    pinyin4j的使用   pinyin4j是一个功能强悍的汉语拼音工具包,主要是从汉语获取各种格式和需求的拼音,功能强悍,下面看看如何使用pinyin4j.     import net.sourc ...

  4. poj1836--Alignment(dp,最长上升子序列变形)

    Alignment Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13319   Accepted: 4282 Descri ...

  5. python+ueditor+七牛云存储整合

    开发环境:python pyramid. 參考网址:http://developer.qiniu.com/docs/v6/sdk/python-sdk.html,http://my.oschina.n ...

  6. cocos2d-x-3.1 事件分发机制 (coco2d-x 学习笔记七)

    触摸事件 Sprite* sp1 = Sprite::create("Images/t1.png"); sp1->setPosition(Vec2(visibleSize.w ...

  7. 为何要fork()两次来避免产生僵尸进程?

    为何要fork()两次来避免产生僵尸进程?   当我们只fork()一次后,存在父进程和子进程.这时有两种方法来避免产生僵尸进程: 父进程调用waitpid()等函数来接收子进程退出状态. 父进程先结 ...

  8. 西南民大oj(矩阵快速幂)

    我的名字不可能那么难记 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 16            测试通过 : ...

  9. POJ 1018 【枚举+剪枝】.cpp

    题意: 给出n个工厂的产品参数带宽b和价格p,在这n个工厂里分别选1件产品共n件,使B/P最小,其中B表示n件产品中最小的b值,P表示n件产品p值的和. 输入 iCase n 表示iCase个样例n个 ...

  10. 浅谈JAVA ThreadPoolExecutor(转)

    这篇文章分为两部分,前面是ThreadPoolExecutor的一些基本知识,后一部分则是Mina中一个特殊的ThreadPoolExecutor代码解析.算是我的Java学习笔记吧. 基础 在我看来 ...