八大排序学习之七堆排序
来源:互联网 发布:淘宝外卖超出配送范围 编辑:程序博客网 时间:2024/05/21 15:01
我们学习堆排序之前需要弄清堆的概念,计算机常说的堆有两种一种是操作系统上的堆内存,还有一种是数据结构上的堆,今天我们来讲数据结构上的堆,数据结构上的堆也有几种,二叉堆,二项堆,斐波那契堆,通常我们把二叉堆成为简称为堆。
堆排序也是一种效率很高的排序,平均时间复杂度为:O(nlogn)
二叉堆是一种完全二叉树,其中非叶结点与父节点的关系总满足,i<=2*1+1&&i<=2*(i+1)或者i>=2*1+1&&i>=2*(i+1)的关系,i为父节点
其中,i<=2*1+1&&i<=2*(i+1)称为小顶堆,i>=2*1+1&&i>=2*(i+1)称为大顶堆。
堆排序的思想如下:
首先将指定的一组数转化成大顶堆或者小顶堆,通过父节点与子节点的比较进行前后替换,通过递归遍历所有节点,每次从顶部取出未排序的最大值跟未排序的最后一个交换, 例如:堆A[0,n-1],先交换a[0]和A[n-1],调整堆,交换A[0]和A[n-2],调整堆......,交换A[0]和a[1],交换完毕。
得出排序结果。
(初始化堆,循环(交换顶部和未排序的最后一个,调整堆)。
举个例子:
第一步、给个数组a[4]={3,1,2,4}
转换得一二叉树
3
1 2
4
第二步、堆化,从第一个非叶结点开始调整,左子节点,1和4交换得
3
4 2
1
第三步继续堆化,3跟4交换得初始大顶堆
4
3 2
1
下面为关键步骤:
第四步,将最顶的与最后的交换,把最大的放到最后面的节点。
1
3 2
4
交换了之后,明显1和3不符合堆的概念,因为需要继续调整
3
1 2
4
最顶的和未排序的最后一个交换,3和2交换得
2
1 3
4
2和1交换得
1
2 3
4
节点访问完毕,得结果。
关键代码:
void max_heapify(int*arr,int index,int len){ int l=2*index+1; int r=2*(index+1); int largest; if(l<len&&arr[l]>arr[index]) largest=l; else largest=index; if(r<len&&arr[r]>arr[largest]) largest=r; if(largest!=index) { //将最大元素提升,并递归 myswap(&arr[largest],&arr[index]); max_heapify(arr,largest,len); }}下面给出完整代码:
// List.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include<stdlib.h>#include <time.h> #define NUMLEN 20000 inline void myswap(int*a,int*b){ *a=*a^*b; *b=*a^*b; *a=*a^*b; }void max_heapify(int*arr,int index,int len){ int l=2*index+1; int r=2*(index+1); int largest; if(l<len&&arr[l]>arr[index]) largest=l; else largest=index; if(r<len&&arr[r]>arr[largest]) largest=r; if(largest!=index) { //将最大元素提升,并递归 myswap(&arr[largest],&arr[index]); max_heapify(arr,largest,len); }}void build_maxheap(int*arr,int len){//建立大顶堆 int i; if(arr==NULL||len<=1) return; for(i=len/2+1;i>=0;--i) max_heapify(arr,i,len);}void heap_sort(int*arr,int len){ int i; if(arr==NULL||len<=1) return; build_maxheap(arr,len); for(i=len-1;i>=1;--i){ myswap(&arr[0],&arr[i]); max_heapify(arr,0,--len); }}int main(int argc, char* argv[]){int a[NUMLEN];srand((int)time(NULL));for(int i=0;i<NUMLEN;i++)a[i]=rand()%NUMLEN;float nstart=clock();heap_sort(a,NUMLEN);for(i=0;i<NUMLEN;i++)printf("%d\n",a[i]);float nend=clock();printf("共用时%.3fs\n",(nend-nstart)/1000);return 0;}20000个数据的时间情况:
- 八大排序学习之七堆排序
- 八大排序之堆排序
- 八大排序之堆排序
- 八大排序之堆排序
- 八大排序 --选择排序 之 【堆排序】
- 八大排序算法之堆排序
- 八大排序算法之堆排序解析
- 八大排序算法之堆排序
- 八大排序--堆排序
- 排序七之堆排序
- 八大排序算法 之 堆排序(二叉树排序)
- 八大排序算法-堆排序
- 八大排序算法--堆排序
- 八大内部排序 -- 堆排序
- 八大排序算法-堆排序
- 八大排序学习之五归并排序
- 八大排序学习之六快速排序
- Java提高 - 八大排序方法之堆排序
- Fragment中调用父Activity中方法的简单方式
- Linux用户root忘记密码的解决(unbuntu16.04)
- 图像分割之(三)从Graph Cut到Grab Cut
- git正确的删除远程仓库的文件并用.gitignore忽略提交此文件
- Android之Context和Activity互相转换
- 八大排序学习之七堆排序
- macOS Sierra下xcode配置opencv2.4.13
- Lesson 18 Nehe
- 封装
- [20]Window PowerShell DSC学习系列---- start-dscconfiguration 中遇到 Access Denied的解决方案
- JSP的爸爸Servlet第一部分总结
- 数据库简介
- uboot 无法通过nfs下载服务器某个文件夹下面的内核
- 基本头部插入式单向链表程序