堆排序
2015-08-22 14:05
218 查看
堆排序用到的是完全二叉树的性质,所以在看这篇文章之前先学习完全二叉树。
http://baike.baidu.com/link?url=HUZLyRNtNhAUzf7rgffW3IHkPbNQF_0vO63EvTKZBgYztrMz02B2_-PlCV5eFg6J8y8w8sHEu4Bd7bZVOXozaK
那么,学会了完全二叉树,现在就可以学习堆排序了。
个人认为,堆排序是插入排序和快排思想的联合,所以读者可以先学会插入排序和快排。
插入排序:每次选出带排序序列的最大值,加入已排好序的序列;
快排:在待排序序列中选择一个记录,让它左边的都比它小,右边的都比它大,如此递归。
思考:
对于插入排序,时间复杂度主要在选择最大值的过程中。有没有一种方法可以用更少的时间就选出最大值呢?
对于快速排序,如果用完全二叉树存储,让根节点比左子树大,比右子树也大,那这个根节点不就是最大值吗?
两相结合,堆排序应运而生,而核心就是完全二叉树的性质。下面可以看看堆排序相关的概念,有助于理解。
http://baike.baidu.com/link?url=Fc3__n67naxdKu_l7MzWi6WCn4QbbJESFSKiJUvvO-CzszGyoqv0coneADUg6DjcJEAVpymvhqwm8qRe9gEYSK
下面是堆排序的代码:
http://baike.baidu.com/link?url=HUZLyRNtNhAUzf7rgffW3IHkPbNQF_0vO63EvTKZBgYztrMz02B2_-PlCV5eFg6J8y8w8sHEu4Bd7bZVOXozaK
那么,学会了完全二叉树,现在就可以学习堆排序了。
个人认为,堆排序是插入排序和快排思想的联合,所以读者可以先学会插入排序和快排。
插入排序:每次选出带排序序列的最大值,加入已排好序的序列;
快排:在待排序序列中选择一个记录,让它左边的都比它小,右边的都比它大,如此递归。
思考:
对于插入排序,时间复杂度主要在选择最大值的过程中。有没有一种方法可以用更少的时间就选出最大值呢?
对于快速排序,如果用完全二叉树存储,让根节点比左子树大,比右子树也大,那这个根节点不就是最大值吗?
两相结合,堆排序应运而生,而核心就是完全二叉树的性质。下面可以看看堆排序相关的概念,有助于理解。
http://baike.baidu.com/link?url=Fc3__n67naxdKu_l7MzWi6WCn4QbbJESFSKiJUvvO-CzszGyoqv0coneADUg6DjcJEAVpymvhqwm8qRe9gEYSK
下面是堆排序的代码:
#include<stdio.h> void creatheap(int *a,int n,int i) //整理堆的函数,包括三个参数,数组首地址,数组元素个数,要处理的结点编号 { if (i*2+1>n) //如果 这个结点没有右孩子 { if (i*2>n) return; //如果再没有左孩子,直接return else //如果有左孩子,就比较这个结点和左孩子是否需要交换 { if (a[i*2]>a[i]) { a[0]=a[i]; a[i]=a[i*2]; a[i*2]=a[0]; creatheap(a,n,2*i); //递归左孩子 } else return; //不需要交换的话直接return } } else //如果有右孩子(那么肯定有左孩子啦~) { if (a[i*2+1]<=a[i]&&a[i*2]<=a[i]) return; //经过比较左右孩子都不需要交换,说明这个堆不用处理了,return else{ //否则,这个堆需要处理 int maxi=i*2; //下面分析需要处理左孩子还是右孩子 if (a[i*2+1]>a[i*2]) maxi++; a[0]=a[i]; a[i]=a[maxi]; a[maxi]=a[0]; creatheap(a,n,maxi); //递归需要处理的那个 } } //这样就完成了一次整理 } int main() { int b[101]={0}; int n; scanf("%d",&n); int i; for (i=1;i<=n;i++) { scanf("%d",b+i); } for (i=n/2;i>=1;i--) //对非叶子结点递减整理,n/2是第一个非叶子结点的编号 { creatheap(b,n,i); } //这样整理完之后目前这个数组是一个堆了 可以确定的是第一个元素b[1]一定是最值 int k=n; while (n!=1) { b[0]=b[1]; b[1]=b ; b =b[0]; n--; creatheap(b,n,1); //把b[1]移到末尾,然后同理整理前n-1个元素,直到n=1 } for (i=1;i<=k;i++) //堆排序完成 { printf("%d ",b[i]); } return 0; }
相关文章推荐
- 258 Add Digits - LeetCode
- Root of AVL Tree (25)
- TPS和事务响应时间的关系【转】
- 多态详解
- 堆和栈的区别(很经典的,正在研究中)
- 自定义注解与mysql整合过滤查询实现
- 下滑栏的实现
- 最大流
- Burp Suite--攻击web 应用程序的集成平台
- Android 实现m3u8视频缓存
- c指针
- input子系统详解
- CRB and His Birthday(完全背包变形)
- struts2 jar包说明
- 从eclipse运行UiAutomator的方法,告别cmd
- pymongo中的连接操作:Connection()与MongoClient()
- Good Bye 2014 C. New Year Book Reading 贪心
- 链表基础
- 接口详解
- 洛谷1307 数字反转