1 数组对象

2 可以视为一棵完全二叉树

3 一个堆可以被看作一棵二叉树和一个数组,如下图所示:

4 下标计算(通常使用内联函数或者宏来定义下标操作):

  • 已知某个结点的下标为i
  • 其父节点下标:i/2向下取整
  • 左孩子下标:2i
  • 右孩子下标:2i+1

5 最大堆:除根节点以外的每个节点i,有A[PARENT(i)] >= A[i]

最小堆:除根节点意外的每个节点i,有A[PARENT(i)] <= A[i]


堆排序

步骤:

  1. 建大顶堆
  2. 去堆顶元素与当前堆的最后一个元素进行互换。
  3. 该堆顶元素已达最终位置,排除出堆
  4. 对剩下的堆进行最大堆调整
  5. 重复2到4步

排序过程

1 建堆过程

1) 从第一个非叶子节点开始,对value为8的节点进行调整,无需调整。

2) 对value值为9的节点进行调整。

3) 对value为2的节点调整

4) 对value为3的节点进行调整

     ----》

5) 对value为7的节点进行调整

  ---》

建堆完成

2 堆顶元素与当前堆的最后一个元素进行互换。

3 该堆顶元素已达最终位置,排除出堆

4 对剩下的堆进行调整

递归进行堆首和堆尾互换以及调整堆的步骤,结果即为排好序的堆。



代码实现

// heapsort.h
class HeapSort:public BaseSort {
public:
HeapSort(int Array[], int len) : BaseSort() {
this-&gt;Array = Array;
this-&gt;len = len;
}
void sort();
private:
/* 建堆 */
void buildMaxHeap(); /* 调整堆,以保持最大堆性质 */
void maxHeapIfy( int i , int curlen); /* 堆排序 */
void heapSort(); /* 返回父节点下标 */
int Parent(int i) {
if ( i % 2 == 0 )
return i/2;
else
return i/2 + 1;
}; /* 返回左孩子节点下标 */
int Left(int i) { return 2 * i + 1; }; /* 返回右孩子节点下标 */
int Right(int i) { return 2 * i + 2; };
private:
int* Array;
int len;
};

相关成员函数实现

// heapsort.cpp
#include "heapsort.h"
void HeapSort::sort() {
heapSort();
}
void HeapSort::heapSort() { buildMaxHeap();
int i = this->len;
int tmp;
while( i > 0 ) {
tmp = this->Array[0];
this->Array[0] = this->Array[i-1];
this->Array[i-1] = tmp;
i--;
maxHeapIfy(0, i);
}
}
void HeapSort::maxHeapIfy( int i, int curlen ) {
int left, right, largest;
int tmp;
left = Left(i);
right = Right(i);
if ( left < curlen-1
&& Array[left] > Array[i])
largest = left;
else
largest = i;
if ( right < curlen-1
&& Array[right] > Array[largest])
largest = right;
if ( largest != i ) {
tmp = Array[i];
Array[i] = Array[largest];
Array[largest] = tmp;
maxHeapIfy(largest, curlen);
}
}
void HeapSort::buildMaxHeap() {
int i;
for ( i = (len-1)/2 ; i >= 0; i-- ) {
maxHeapIfy(i, len);
if (DEBUG) {
printArray(this->Array, this->len, "midResult");
}
}
}

测试代码:

 /* --------- HeapSort -------- */
int b[10] = {7,3,2,9,8,5,1,10,4,6};
HeapSort* heapsort = new HeapSort(b, len);
heapsort->sort();
printArray(b, len, "HeapSort ");

参考资料:

《算法导论 2rd》

http://www.cnblogs.com/Anker/archive/2013/01/23/2873422.html  《算法导论》读书笔记之第6章 堆排序

排序算法(2) 堆排序 C++实现的更多相关文章

  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++编程练习(13)----“排序算法 之 堆排序“

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

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

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

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

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

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

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

  9. 排序算法FOUR:堆排序HeapSort

    /** *堆排序思路:O(nlogn) * 用最大堆,传入一个数组,先用数组建堆,维护堆的性质 * 再把第一个数与堆最后一个数调换,因为第一个数是最大的 * 把堆的大小减小一 * 再 在堆的大小上维护 ...

随机推荐

  1. mongodb二进制安装与yum安装

    一.什么是mongodb MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当 ...

  2. springboot-9-在springboot中引入bean

    在非spring管理的包中引入spring管理的类, 可以使用一个类继承ApplicationContextAware即可 分两种, 第一种该类在spring的包扫描范围之下: package com ...

  3. 在你的 Rails App 中开启 ETag 加速页面载入同时节省资源

    转自http://huacnlee.com/blog/use-etag-in-your-rails-app-to-speed-up-loading/ 什么是 ETag 网上关于 ETag 的解释有很多 ...

  4. SpringMVC源码阅读:Controller中参数解析

    1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...

  5. java之Lombok

    Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法 pom依赖: <dependency ...

  6. C#异步,多线程下的HttpContext丢失问题

    1.思路概述 首先让我把大概的一个思路先说一遍吧. 我在一个页面中要同时调用两个接口,而我要给这些接口一些参数:就是我通过HttpContext.Current.Request.QueryString ...

  7. Algorithm——两个排序数组的中位数

    ps:城际的网速还是不错的-

  8. webpack开发工具

    source map 用来调试打包后的代码 const path = require('path'); const HtmlWebpackPlugin = require('html-webpack- ...

  9. iview select下拉bug

    1场景:弹框内有一个下拉组件(支持搜索),当选择完数据后弹框关闭,再次打开后,下拉框内的数据是刚才选中的数据.原因:分析后觉得是搜索内容没有清空,导致下拉的数据只有一个解决:调用下setQuery方法 ...

  10. Hive安装与应用过程

    1.  参考说明 参考文档: https://cwiki.apache.org/confluence/display/Hive/GettingStarted 2.  安装环境说明 2.1.  环境说明 ...