堆排序的时间效率与快速排序
相同,也为O(n * log n)。空间上没有使用多余的空间。
基于数组堆的相关定义算法见Heap 堆
排序基于以下假设:
如果一个节点的两个子堆是正确,可以通过下降trickleDown使得堆恢复正常。
一个无序数组的n/2~n的数字可以看成为没有子堆的正确的堆。
对从n/2-1 至 0的元素依次调用trickleDown,可以将一个无序数组组中成一个正确的堆
只有一个节点的堆是个正确的堆
移除总是移除最大的元素,且每次移除后数组的从后向前多增加自由位置,可以将刚移除的数据放入其中。
Node为辅助类,key表示排序关键字,value表示数据。为了简便没有采用标准的get,set
Heap中
构造函数根据给定的需要排序的数组构造。
sort方法:首先将数组变成一个正确的堆,然后将堆中的数据依次取出放回数组。
trickleDown:将数组中的指定位置元素下降至恰当的位置,以保证堆的正确性。
print,main:提供简单的测试。
class Node { //表示装数据的节点
private int key; //排序的关键字
private Object value; //数据
Node(int key, Object value) {
this.key = key;
this.value = value;
}
int key() { return key; }
Object value() { return value; }
}
class Heap {
private Node[] array; //序排序的数组
private int pos; //当前有效数据的个数
Heap(Node[] array) {
this.array = array; //装入要排序的数组
pos = array.length;
}
private Node remove() { //删除堆的顶
Node result = array[0];
array[0] = array[--pos]; //将最后一个元素提至堆定
trickleDown(0); //将堆顶下降为恰当位置
return result;
}
private void trickleDown(int index) {
Node top = array[index]; //存放要下降的数据
int left = getLeft(index); //得到左子的位置
int right = getRight(index); //得到右子的位置
int current; //当前可能要下降的位置
if(left < pos && right < pos) //左右子节点有效,当前的位置设置为左右子节点中小的那个
current = array[left].key() > array[right].key() ? left : right;
else if (left < pos) current = left; //如果左子节点有效,则当前位置设置为左子节点
else current = -1; //没有可以下降的位置
while(current != -1 && array[current].key() > top.key()) {//当前节点有效且大于要下降的数据
array[index] = array[current]; //将当前节点向上提升。
index = current; //重复以上过程
left = getLeft(index);
right = getRight(index);
if(left < pos && right < pos)
current = array[left].key() > array[right].key() ? left : right;
else if (left < pos) current = left;
else current = -1;
}
array[index] = top; //将暂存的数据放入恰当的位置
}
private int getParent(int index) {
return (index-1)/2;
}
private int getLeft(int index) {
return 2 * index + 1;
}
private int getRight(int index) {
return 2 * index + 2;
}
public void sort() {
for(int i=array.length/2 -1; i>=0; i--) {
trickleDown(i);
}
for(int i=array.length-1; i>=0;i--) array[i] = remove();
}
public static void main(String[] args) {
Node[] nodes = {new Node(50,"hello"),
new Node(20,"jason"),
new Node(60,"peter"),
new Node(50,"orange"),
new Node(30,"temp"),
new Node(40,"hello"),
new Node(90,"nasen"),
new Node(25,"kaka")};
Heap heap = new Heap(nodes);
heap.sort();
print(nodes);
}
private static void print(Node[] nodes) {
for(Node node: nodes)
System.out.println(node.key() + "-----" + node.value());
}
}
分享到:
相关推荐
最快的排序算法 谁才是最强的排序算法:快速排序-归并排序-堆排序,排序算法数据结构
算法-理论基础- 排序- 堆排序(包含源程序).rar
C语言版的排序方法---堆排序,非常有用的代码,可以实际中使用。
常用的排序算法--堆排序,通过创建堆的方法进行排序
堆排序--大顶堆排序
Java代码-排序-直接插入排序、希尔排序、直接选择排序、冒泡排序、堆排序、快速排序、归并排序中部分排序以及算法-贪心法,大家可以将源码下载下来进行学习,附带着注释和解释,有不理解的可以找博主一起探讨,共同...
详解Java常用排序算法-堆排序
多线程实现排序算法的比较:希尔排序、快速排序、堆排序。用java语言实现,很经典,需要的可以下载看看!
堆排序-flash演示 可自己输入数据............
该程序通过利用基本的存储结构堆对线性表进行排序,突出强调了堆的重要性。
8.12-8.19_冒泡_选择_插入_希尔_快速_归并_基数_堆排序_排序算法Swift代码及UI演示
学习笔记
各种排序算法,包括希尔算法,快速排序,堆排序-A variety of sorting algorithms, including the Hill algorithm, quick sort, heap sort
自己看书时写的排序算法:堆排序 CPP文件
该资源提供了Java中实现堆排序的全面指南。文档中涵盖了堆排序的基本概念,包括如何对数组进行排序以及如何在Java中实现堆排序。此外,文档还包括一个逐步指南,介绍了如何在Java中实现堆排序,包括详细的代码示例和...
c语言实现堆排序。代码实现的是建立大根堆
全面的排序算法实现,包括插入排序、合并排序、堆排序、快速排序。 堆排序:HeapSort 讲解详见http://blog.csdn.net/fly_yr/article/details/8550701 插入排序:InSertion_Sort 讲解详见...
堆排序
实验内容及要求: 输入n个整数,分别用希尔排序、快速排序、堆排序和归并排序实现由小到大排序并输出排序结果。要求n=10,15,20进行三组排序实验。 实验目的:掌握希尔排序、快速排序、堆排序、归并排序算法。
(1) 完成5种常用内部排序算法的演示,5种排序算法为:快速排序,直接插入排序,选择排序,堆排序,希尔排序; (2) 待排序元素为整数,排序序列存储在数据文件中,要求排序元素不少于30个; (3) 演示程序开始,...