排序算法——堆排序
2015-07-21 13:33
190 查看
堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。
二叉堆是完全二叉树或者是近似完全二叉树。
二叉堆满足二个特性:
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。下图展示一个最小堆:
由于其它几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆。
一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。
下面先给出《数据结构C++语言描述》中最小堆的建立插入删除的图解,再给出本人的实现代码,最好是先看明白图后再去看代码。
每次插入都是将新数据放在数组最后。可以发现从这个新数据的父结点到根结点必然为一个有序的数列,现在的任务是将这个新数据插入到这个有序数据中——这就类似于直接插入排序中将一个数据并入到有序区间中,对照《白话经典算法系列之二
直接插入排序的三种实现》不难写出插入一个新数据时堆的调整代码。
二叉堆的定义
二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足二个特性:
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。下图展示一个最小堆:
由于其它几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆。
堆的存储
一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。
堆的操作——插入删除
下面先给出《数据结构C++语言描述》中最小堆的建立插入删除的图解,再给出本人的实现代码,最好是先看明白图后再去看代码。
堆的插入
每次插入都是将新数据放在数组最后。可以发现从这个新数据的父结点到根结点必然为一个有序的数列,现在的任务是将这个新数据插入到这个有序数据中——这就类似于直接插入排序中将一个数据并入到有序区间中,对照《白话经典算法系列之二直接插入排序的三种实现》不难写出插入一个新数据时堆的调整代码。
// tt.cpp : 定义控制台应用程序的入口点。 // //堆排序思想(升序):先建立大顶堆,把最大的顶拉倒最后边,再进行堆调整 #include "stdafx.h" void AjustHeap(int a[], int count, int current) { int lchild = 2*current + 1; int rchild = 2*current + 2; int max = current; if (lchild<=count-1 && a[lchild] > a[max]) { max = lchild; } if (rchild<=count-1 && a[rchild] > a[max]) { max = rchild; } if (max != current) { int temp = a[current]; a[current] = a[max]; a[max] = temp; //对变动子节点进行递归,保证大顶堆 AjustHeap(a, count, max); } } void sort(int a[], int count) { //建立大顶堆 for (int i=count/2 - 1; i>=0; i--) { AjustHeap(a, count, i); } //不断地调整 for (int i=count; i>=1; i--) { int temp = a[0]; a[0] = a[i-1]; a[i-1] = temp; //最后一个元素就不再参与调整了 AjustHeap(a,i-1,0); } } int _tmain(int argc, _TCHAR* argv[]) { int a[10] = {5,7,4,9,0,8,1,2,6,3}; sort(a, 10); return 0; }
相关文章推荐
- java生成word
- 一、Solr综述
- 魔方公式xyz
- vim进阶使用
- matlab产生正态分布样本
- Hibernate4.x框架之一简介及入门实例
- (调试。F5F6F8,F5进入方法内部,F6逐行执行,F8跳过方法)
- 面向 Perl 开发人员的 XML,第 2 部分: 使用到 Perl 的高级 XML 解析技术
- jquery 插件封装总结
- 学习笔记9:Scala外部类和内部类
- SharedPreferences的跨应用读/写
- %后面字母含义&如何发现系统中堆栈的大致位置
- CTreeCtrl之排序
- 九宫格布局
- Android Networking I: OkHttp, Volley and Gson
- 关于SAP中物料双单位的解析
- Financial Management
- oracle学习笔记(转)
- css中用一张背景图做页面的技术有什么优势?
- ios常用的几种反向传值