算法导论------堆排序heapsort
来源:互联网 发布:大数据对旅游业的影响 编辑:程序博客网 时间:2024/04/30 14:41
目录
- 1.堆排序概述
- 2.二叉堆
- 3.二叉堆的存储
- 4.维护堆的性质
- 4.1递归实现maxHeapify函数
- 4.2非递归实现maxHeapify函数
- 5.建堆操作
- 5.1从下向上、从右向左建堆(C实现)
- 5.2从上向下、从左向右建堆(C实现)
- 6.堆排序
- 7.堆排序C代码实现
- 8.参考资料
1.堆排序概述
简单选择排序是:假设排序序列为
如果每趟排序可以在找到最小(大)元素的同时,根据比较结果对其它记录做出调整(逆序交换),那么简单选择排序的效率就会大大提高。于是Floyd和Williams在1964年发明了Heap Sort(堆排序)方法,对简单选择排序进行改进,所以堆排序也是选择排序算法中的一种。
堆排序是一种基于完全二叉树的树形选择排序 方法。在排序的过程中将待排序列看成是一颗完全二叉树的顺序存储结构,树上的每一个结点对应数组中的一个元素,可以利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序序列中构建“二叉堆”,简称“建堆”操作。从而在二叉堆的根部找到关键字最大(小)的元素。这种叫“堆”的数据结构可以保存每趟排序过程中的中间比较结果。堆按性质可分为大顶堆和小顶堆。如果想让序列按升序(降序)排序,就需要将待排序的n个元素构造成大顶堆(小顶堆)。此时堆顶即为最大值(最小值),将它和堆数组的尾元素交换,堆数组长度减1。然后将剩余的n-1个待排元素重新建堆,从而得到n个元素中的次大元素,将它和堆数组的尾元素交换,堆数组长度减1。反复迭代,最终得到一个有序的序列。
堆排序具有空间原址性(in space),即任何时候都只需要常数个额外的元素空间存储临时数据。
2.二叉堆
(二叉)堆是具有下列性质的完全二叉树:
每个结点的值
L[i] 都大于或等于其左孩子L[left(i)] 和右孩子L[right(i)] 结点的值,称为大顶堆(最大堆);
每个结点的值L[i] 都小于或等于其左孩子L[left(i)] 和右孩子L[right(i)] 结点的值,称为小顶堆(最小堆);
从二叉堆性质中,可以看到根节点一定是所有结点的最小(大)值。较小(大)的结点和根结点的距离较近。
3.二叉堆的存储
二叉堆在内存中是用数组存储的。
如果堆的根结点为
如果堆的根结点为
4.维护堆的性质
堆排序算法中,最关键的就是构造初始堆。需要编写一个维护大顶堆性质的函数Max_Heapify。当输入一个数组L和一个下标i,然后调用Max_Heapify时,比较
4.1递归实现maxHeapify函数
void maxHeapify(int arr[],int i,int heapsize) {//递归实现 int left=2*i+1; int right=2*i+2; int largest; if (left<=heapsize && arr[left]>arr[i]) largest=left; else largest=i; if (right<=heapsize && arr[right]>arr[largest]) largest=right; if(largest!=i) { swap(&arr[largest],&arr[i]); maxHeapify(arr,largest,heapsize); }}
4.2非递归实现maxHeapify函数
void maxHeapify(int arr[],int i,int heapsize) {//非递归实现 int left=2*i+1; int right=2*i+2; int largest; while(left<=heapsize) { if (arr[left]>arr[i]) largest=left; else largest=i; if (right<=heapsize && arr[right]>arr[largest]) largest=right; if(largest!=i) { swap(&arr[largest],&arr[i]); i=largest; //从上向下维护堆性质;所以要更新根节点、左右节点的索引; left=2*i+1; right=2*i+2; } else { break; } }}
5.建堆操作
对一个长度为length的数组
5.1从下向上、从右向左建堆(C实现)
void buildMaxHeap(int arr[],int heapsize) {//实现1 for(int i=(heapsize-1)/2; i>=0; i--) {//从下向上,从右向左维护堆性质 maxHeapify(arr,i,heapsize); }}
5.2从上向下、从左向右建堆(C实现)
当数组仅有
void buildMaxHeap(int arr[],int heapsize) { //实现2 if(heapsize==0) return; for(int i=1;i<=heapsize;i++){ int index=i; int parent=floor((index-1)/2); //floor函数定义在<math.h>中; while(parent>=0 && arr[parent]<arr[index]){ swap(&arr[parent],&arr[index]); //arr[0]元素父节点arr[-1],循环中断; index=parent; parent=floor((index-1)/2); //不加floor函数,可以把arr[0]的父节点看成是自身; } }}
6.堆排序
将待排序的length个元素构造成大顶堆。此时堆顶
//从arr[length-1]到arr[1]依次调用buildMaxHeap,最终实现排序void heapSort(int arr[],int len) { buildMaxHeap(arr,len-1); for(int i=len-1; i>0; i--) { swap(&arr[0],&arr[i]); //buildMaxHeap(arr,i-1);此处无需从新建堆,从新维护堆性质即可 maxHeapify(arr,0,i-1); }}
7.堆排序C代码实现
#include <stdio.h>#include <stdlib.h>int arrtest[100];void swap(int *a,int *b) { int temp=*a; *a=*b; *b=temp;}void maxHeapify(int arr[],int i,int heapsize) { //维护堆的性质,可以用非递归实现 int left=2*i+1; int right=2*i+2; int largest; if (left<=heapsize && arr[left]>arr[i]) largest=left; else largest=i; if (right<=heapsize && arr[right]>arr[largest]) largest=right; if(largest!=i) { swap(&arr[largest],&arr[i]); maxHeapify(arr,largest,heapsize); }}void buildMaxHeap(int arr[],int heapsize) { //建堆 for(int i=(heapsize-1)/2; i>=0; i--) { maxHeapify(arr,i,heapsize); }}void heapSort(int arr[],int len) { //堆排序 buildMaxHeap(arr,len-1); for(int i=len-1; i>0; i--) { swap(&arr[0],&arr[i]); //buildMaxHeap(arr,i-1);//此处无需从新建堆,从新维护堆性质即可 maxHeapify(arr,0,i-1); }}void PrintArray(int arr[],int length) { //打印数组,用于查看排序效果 printf("["); for(int i=0; i<length; i++) { if(i==length-1) printf("%d]\n",arr[i]); else printf("%d ,",arr[i]); }}int main() { int num=0; printf("请输入数组元素个数:"); scanf("%d",&num); for(int i=0; i<num; i++) { //读入待排序数据 scanf("%d",&arrtest[i]); } printf("排序前数据为:"); PrintArray(arrtest,num); heapSort(arrtest,num); printf("排序后数据为:"); PrintArray(arrtest,num); return 0;}
8.参考资料
- 《2013数据结构联考复习指导》 王道论坛 组编
- 《算法导论 (原书第3版)》 机械工业出版社
- 《大话数据结构》 清华大学出版社 程杰 著
- 算法导论------堆排序heapsort
- c++堆排序实现(heapsort) (算法导论)
- 【算法导论学习-013】堆排序(Heapsort)
- 堆排序HeapSort算法学习
- HeapSort(堆排序算法)
- 经典算法---堆排序(Heapsort)
- 排序算法 之 堆排序(heapsort)
- java排序算法_013堆排序(Heapsort)
- 排序算法 之 堆排序 HeapSort
- 经典排序算法-堆排序HeapSort
- Java排序算法--堆排序(HeapSort)
- 经典算法(9)- 堆排序(Heapsort)
- 算法学习 - 堆排序 ( HeapSort ) C++实现
- Java堆排序(HeapSort)算法实现
- Heapsort 堆排序算法详解(Java实现)
- 堆排序算法的实现(HeapSort)
- Heapsort 堆排序算法详解(Java实现)
- 算法导论 堆排序
- 测试1130
- Nmap使用说明及原理分析
- JVM(四)——垃圾回收机制
- Java对象的序列化和反序列化
- Android的各种Drawable讲解
- 算法导论------堆排序heapsort
- Linux netstat命令详解
- java的Set类和Hashset类
- OSI七层模型
- [算法]Floyd-Warshall算法理解
- WIN7中全新安装WIN7
- POJ3268————Silver Cow Party(最短路)
- Android UiAutomator环境配置与编译运行
- 【SSH】java真分页实现