堆排序虽然叫heap sort,但是和内存上的那个heap并没有实际关系。算法上,堆排序一般使用数组的形式来实现,即binary heap。

我们可以将堆排序所使用的堆int[] heap视为一个完全二叉树,即,除非最后一层右侧有空结点,其他都为满结点。

对于任意heap[i]有如下一些性质:

1. i从1开始。

2. heap[i]的父节点为heap[i / 2]。

3. heap[i]的左子节点为heap[i * 2],右子节点为heap[i * 2 + 1]。

我们假设这个堆是一个最大堆,也就是父节点大于所有子节点,而且每个子树也有这样的性质。下面几个和堆排序有关的方法,基本来自于《算法导论》中的思路。

maxifyHeap方法,堆中index这个位置的结点破坏了整个堆的性质,但是其他结点的位置就是对的。我们首先将heap[index]和它左右子节点中,较大的那个交换位置,比如是left,然后递归调用maxifyHeap(left)。为什么假设只有index这个结点位置不对?因为这个方法一般是在建堆之后调用,也就是基于heap已经是最大堆的事实。这个方法的时间复杂度为O(logn)。

buildMaxHeap方法,建堆。也就是在堆在初始状态,很乱的时候,首次调用。思路是:从树的倒数第二层的最后一个有子节点的结点开始,递归调用上面的maxifyHeap方法。注意,开始的结点必然是heapLength,终点是1。时间复杂度为O(n)。

heapSort方法,首先用buildMaxHeap建堆,然后将堆顶元素和最后一个元素交换位置,这时候最后一个元素肯定到位了,最大。但是第一个元素交换过来的肯定不该在第一位,注意,这时其他结点仍然没有破坏最大堆的性质。所以我们只要调用maxifyHeap(1)就可以了。所以我们,循环这样做,每次将堆顶元素和最后一个元素交换位置,同时heapLength--。直到heapLength==1。时间复杂度为O(nlogn)。

public class BinaryHeap {
static int heapLength; public static void maxifyHeap(int[] heap, int index) {
if(index > heapLength) {
return;
}
int left = index * 2, right = index * 2 + 1;
int larger = -1;
if(left <= heapLength) {
if(heap[left] > heap[index]) {
larger = left;
}
}
if(right <= heapLength) {
if(heap[right] > heap[index] && heap[right] > heap[left]) {
larger = right;
}
}
swap(heap, index, larger);
maxifyHeap(heap, larger);
} public static void buildMaxHeap(int[] heap) {
for(int i = heapLength / 2; i >= 1; i--) {
maxifyHeap(heap, i);
}
} public void heapSort(int[] heap) {
buildMaxHeap(heap);
for(int i = heapLength; i >= 1; i--) {
swap(heap, 1, i);
heapLength--;
maxifyHeap(heap, 1);
}
} public static void swap(int[] heap, int index1, int index2) {
int temp = heap[index1];
heap[index1] = heap[index2];
heap[index2] = temp;
}
}

参考http://www.cnblogs.com/yangecnu/p/Introduce-Priority-Queue-And-Heap-Sort.html

堆排序 Heap Sort的更多相关文章

  1. 数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)

    堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排 ...

  2. Python入门篇-数据结构堆排序Heap Sort

    Python入门篇-数据结构堆排序Heap Sort 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.堆Heap 堆是一个完全二叉树 每个非叶子结点都要大于或者等于其左右孩子结点 ...

  3. 算法----堆排序(heap sort)

    堆排序是利用堆进行排序的高效算法,其能实现O(NlogN)的排序时间复杂度,详细算法分析能够点击堆排序算法时间复杂度分析. 算法实现: 调整堆: void sort::sink(int* a, con ...

  4. 堆排序Heap sort

    堆排序有点小复杂,分成三块 第一块,什么是堆,什么是最大堆 第二块,怎么将堆调整为最大堆,这部分是重点 第三块,堆排序介绍 第一块,什么是堆,什么是最大堆 什么是堆 这里的堆(二叉堆),指得不是堆栈的 ...

  5. Java实现---堆排序 Heap Sort

    堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关 ...

  6. 小小c#算法题 - 7 - 堆排序 (Heap Sort)

    在讨论堆排序之前,我们先来讨论一下另外一种排序算法——插入排序.插入排序的逻辑相当简单,先遍历一遍数组找到最小值,然后将这个最小值跟第一个元素交换.然后遍历第一个元素之后的n-1个元素,得到这n-1个 ...

  7. 数据结构与算法---堆排序(Heap sort)

    堆排序基本介绍 1.堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序. 2.堆是具有以下性质的完全二叉树:每个 ...

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

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

  9. 堆排序(Heap Sort)的C语言实现

    堆排序(Heap Sort)具体步骤为 将无序序列建成大顶堆(小顶堆):从最后一个非叶子节点开始通过堆调整HeapAdjust()变成小顶堆或大顶堆 将顶部元素与堆尾数组交换,此是末尾元素就是最大值, ...

随机推荐

  1. golang的内存模型与new()与make()

    要彻底理解new()与make()的区别, 最好从内存模型入手. golang属于c family, 而c程序在unix的内在模型: |低地址|text|data|bss|heap-->|unu ...

  2. 在WIN7下安装运行mongodb 1)、下载MongoDB

    1).下载MongoDB http://downloads.mongodb.org/win32/mongodb-win32-i386-2.4.5.zip 下载Windows 32-bit版本并解压缩, ...

  3. Xcode全局断点

    1.将导航器视图切换到断点导航器视图下,也可以用快捷键Command+7一步搞定,键盘是window风格的用户Command键是win键(有微软logo),然后点击左下角的+号,选择Add Symbo ...

  4. Linux下cron的使用

    cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业.由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动.关闭这个服务: /sbin/service c ...

  5. [转]IP_ADD_MEMBERSHIP : 组播错误 的解决方法:

    [转]IP_ADD_MEMBERSHIP : 组播错误 的解决方法: http://www.cnitblog.com/dvb-dvb/archive/2012/10/15/aa.html by def ...

  6. INPC & RaizePropertyChanged in mvvmlight

    INPC & RaizePropertyChanged in mvvmlight In WPF app, MvvM Framework, we binding the UIElement fr ...

  7. 44.do文件格式

    style1: transcript onif {[file exists rtl_work]} {<span style="white-space:pre"> < ...

  8. Graceful degradation versus progressive enhancement

    http://ued.taobao.org/blog/2008/10/understanding-progressiveen-hancement-chs-translation/ http://www ...

  9. Differences Between Xcode Project Templates for iOS Apps

    Differences Between Xcode Project Templates for iOS Apps When you create a new iOS app project in Xc ...

  10. Ruby 多线程探索实践与归纳总结

    Ruby 多线程 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程. 线程是程序中一个单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程. Ruby 中我们可以通 ...