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. springcloud-06-feign的使用

    在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Ap ...

  2. [转]Asp.net Mvc 与WebForm 混合开发

    本文转自:https://www.cnblogs.com/dooom/archive/2010/10/17/1853820.html 根据项目实际需求,有时候会想在项目中实现Asp.net Mvc与W ...

  3. 线程9--NSOperation

    一.NSOperation简介  1.简单说明  NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程  NSOperation和NSOpe ...

  4. MySQL4:索引

    什么是索引 索引是对数据库表中一列或者多列的值进行排序的一种结构,所引用于快速找出在某个 列中有一特定值的行.不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行.表越大,查询数据所 ...

  5. mysql中的坑

    1,MySQL建表中double类型不能限制数据长度! 2,……

  6. yum 安装php7.1

    yum install http://rpms.remirepo.net/enterprise/remi-release-6.rpm yum -y install php71-php.x86_64 p ...

  7. C# 一个方法如何返回多个值

    通常一个方法只能返回一个值,但是如果在某些时候,我们想要返回多个值,例如某个方法将一个浮点数分割成一个整数和一个小数返回.这个时候我们就要用到out关键字. using System; namespa ...

  8. angualrJs实现图片上传功能

    整体逻辑:service提供FileReader函数,directive提供点击事件的绑定和监听,controller用来修改html上的ng-src属性值 1.HTML <input type ...

  9. 空间数据的WKT和WKB表现形式

    WKT(well-known text)是一种文本标记语言,该格式由开放地理空间联盟(OGC)制定,用于表示矢量数据中的几何对象,在数据传输与数据库存储时,常 用到它的二进制形式,即WKB(well- ...

  10. C# SqlConnection连接sql server

    try { SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Data Source=127.0.0.1; ...