一. 定义
- 任何关键字data[0...n]都可以组成一个完全二叉树。
- 堆就是一种特殊的二叉树:树中任一非叶结点的关键字均大于等于(或小于等于)其左右孩子(若存在)结点的关键字。
- 大于等于称为大根堆;小于等于称为小根堆。
二. 排序方法(以大根堆为例)
- 先将初始文件data[1..n]建成一个大根堆,此堆为初始的无序区。
- 将关键字最大的记录data[0](即堆顶)和无序区的最后一个记录data[n]交换,由此得到新的无序区data[0..n-1]和有序区data[n],且满足data[1..n-1]≤data[n]。
- 由于交换后新的根data[0]可能违反堆性质,故应将当前无序区data[0..n-1]调整为堆。然后再次将data[1..n-1]中关键字最大的记录data[0]和该区间的最后一个记录data[n-1]交换,由此得到新的无序区data[0..n-2]和有序区data[n-1..n],且仍满足关系data[0..n-2]≤data[n-1..n],同样要将data[0..n-2]调整为堆...直到无序区只有一个元素为止。
三. 动画演示
http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/duipaixu.htm
四. Java代码
private static int parentIdx(int childIdx) {
return (childIdx - 1) / 2; //索引从0开始, 注意childIdx=0时返回0
}
private static int leftChildIdx(int parentIdx) {
return parentIdx*2 + 1;
}
/**
* 构建大顶堆.
*/
private static void buildMaxHeap(int[] datas) {
int lastIdx = datas.length -1;
for(int i=parentIdx(lastIdx); i>=0; i--) { //几个父节点
int k = i; //当前父节点k=i
while(leftChildIdx(k) <= lastIdx) {
int j = leftChildIdx(k);
if(j < lastIdx) { //有两个孩子
if(datas[j] <= datas[j+1]) { //右孩子比较大, 选择大的
j++;
}
}
if(datas[k] >= datas[j]) { //父的比较大
break;
} else {
SortUtil.swap(datas, k, j);
k = j; //父节点重新赋值为原父节点的左孩子节点或者右孩子节点
}
}
}
}
/**
* 堆顶改变, 要维护大顶堆.
*/
private static void maintainMaxHeap(int[] datas, int lastIdx) {
int k = 0;
while(k <= parentIdx(lastIdx)) {
int j = leftChildIdx(k);
if(j < lastIdx) { //有两个孩子
if(datas[j] <= datas[j+1]) { //j+1 比较大, 选择大的
j++;
}
}
if(datas[k] < datas[j]) { //父结点比较小
SortUtil.swap(datas, k, j);
k = j;
} else {
break;
}
}
}
public static int[] sort(int[] datas) {
buildMaxHeap(datas);
int lastIdx = datas.length - 1;
while(lastIdx > 0) {
SortUtil.swap(datas, 0, lastIdx);
lastIdx--;
if(lastIdx > 0) {
maintainMaxHeap(datas, lastIdx);
}
}
return datas;
}
五.时间复杂度和稳定性
- 堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成。
- 堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均性能较接近于最坏性能。
- 由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。
- 堆排序是就地排序,辅助空间为O(1)。
- 堆排序是不稳定的排序方法。
六.堆排序和直接插入排序
直接选择排序中,为了从data[0..n]中选出关键字最小的记录,必须进行n-1次比较,然后在data[2..n]中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。
堆排序可通过树形结构保存部分比较结果,可减少比较次数。
分享到:
相关推荐
《数据结构与算法分析:C语言描述》曾被评为20世纪顶尖的30部计算机著作之一,作者在数据结构和算法分析方面卓有建树,他的数据结构和算法分析的著作尤其畅销,并受到广泛好评,已被世界500余所大学选作教材。...
《数据结构算法与应用-C++语言描述》这本书,由Sahni著,旨在帮助读者深入理解这些核心概念,并通过C++实践来提升技能。 本书可能涵盖了以下几个主要的知识点: 1. **基础数据结构**:包括数组、链表、栈、队列、...
3. **排序与查找算法**:排序算法(如冒泡排序、插入排序、选择排序、快速排序、归并排序、堆排序)和查找算法(如线性查找、二分查找、哈希查找)是算法的基础。书中会详细分析每种算法的时间复杂度和空间复杂度,...
- **八大排序算法**:包括冒泡排序、插入排序、选择排序、快速排序、归并排序、堆排序、希尔排序和计数排序。每种算法都有其特定的应用场景和效率特点。 4. **查找算法**: - **哈希表**:通过哈希函数快速定位...
数据结构课程设计是计算机科学教育中的重要组成部分,它涉及到如何高效地组织和处理数据,而排序算法则是数据结构中的一项基础但至关重要的内容。在这个课程设计中,我们重点关注了六种经典的内部排序算法:直接插入...
数据结构与算法是计算机科学的基础...通过上述资源,你可以系统地学习数据结构与算法,不断积累实践经验,提升编程能力。记住,理解和掌握数据结构与算法是提升编程技能的关键步骤,也是通往高级软件工程师之路的基石。
《数据结构与算法分析——C++描述》是Mark Allen Weiss教授撰写的一本经典教材,针对计算机科学中的核心主题——数据结构和算法进行了深入浅出的阐述。这本书的第三版不仅涵盖了基本的数据结构如数组、链表、栈、...
《数据结构与算法分析C++语言描述第四版》是一本深度探讨数据结构和算法的经典教材。这本书由Mark Allen Weiss撰写,旨在帮助读者理解和掌握如何在C++编程环境中有效地设计和实现数据结构及算法。第四版更新了内容,...
《数据结构算法与应用:C++语言描述》这本书旨在深入浅出地介绍数据结构的基本概念、设计原理以及C++中的实现方式,并结合习题来帮助读者巩固理解和提高实践能力。 本书首先会讲解基本的数据结构,如数组、链表、栈...
- 堆排序:利用堆结构实现的排序算法。 - 计数排序、桶排序、基数排序:适合特定场景的非比较排序。 2. **搜索算法**: - 线性搜索:最简单的搜索方法,时间复杂度为O(n)。 - 二分搜索:适用于已排序的数组,...
《数据结构与算法分析:C语言描述》是计算机科学领域的一本经典著作,由Mark Allen Weiss撰写,旨在深入探讨数据结构和算法,并采用C语言作为实现工具。这本书的第二版在原有基础上进行了更新和改进,增加了更多的...
数据结构是计算机科学中的核心概念,它涉及到如何高效地存储和操作数据。堆排序是一种基于比较的排序...理解并实践这些函数的编写,不仅能帮助我们掌握堆排序算法,也能增强我们在实际编程中的数据结构和算法运用能力。
本资源包含的数据结构与算法课后习题答案,是学习这一领域的重要辅助材料,可以帮助学生深入理解和巩固所学知识。 在数据结构部分,常见的有数组、链表、栈、队列、树(二叉树、平衡树、堆)、图等。数组是最基础的...
《数据结构与算法Java》是由周鹏编著的一本深入探讨数据结构与算法的书籍,主要面向Java开发者。这本书详细地介绍了数据结构和算法的基础知识,对于提升编程能力,优化程序设计有着重要的指导意义。 首先,我们要...
6. 堆排序:利用堆这种数据结构,将序列构造成一个大顶堆或小顶堆,然后每次将堆顶元素与末尾元素交换,再调整堆。 7. 计数排序、桶排序和基数排序:这三种属于非比较型排序,适用于特定场景,如数值范围较小、数据...
根据提供的文件信息,这里主要关注的是“C++数据结构与算法(第4版)”这一主题,虽然实际内容并未给出具体章节或知识点,但我们可以基于标题、描述以及部分已知内容来推测书中可能涵盖的关键知识点。 ### C++数据...
在这个主题中,"Java数据结构与算法中的源代码和applet" 提供了深入学习的机会,通过实际的源代码和交互式的Applet来体验和理解各种数据结构和算法。 1. **数据结构**: - **数组**:最基础的数据结构,提供固定...
资源摘要信息是关于Java数据结构和算法的知识点总结,涵盖了数组、栈与队列、链表、递归、哈希表、高级排序、二叉树、红黑树、堆、带权图等数据结构和算法概念。 一、数组 * 数组是相同类型变量的集合,可以使用...
全书共分为六个部分,分别涵盖了数据结构的基本概念、数组、简单的排序算法、栈与队列、链表、递归等内容,并深入探讨了高级排序算法、二叉树、红黑树、2-3-4树以及外部存储、哈希表、堆、图和加权图等高级主题。...
- **堆排序与优先队列**:堆可以作为优先队列的数据结构,实现插入、删除最大元素等操作。 4. **稳定性**:排序算法的稳定性是指相等的元素在排序后相对位置是否改变。稳定排序算法如冒泡排序、插入排序、归并排序...