郭郭自学笔记(2):堆排序2.0
2016-07-14 00:35
190 查看
由于第一次写博客的狼狈(写了一堆话,忘了保存,导致重写),接下来写准备以(题目-分析-代码)的形式去写。
题目一:寻找一组数据中第K大的数
分析:
题目描述很简单,完全可以将所有的数据从大到小进行排序,选取第K个数,便可以解决我们的问题,这样的话,时间复杂度就将取决于我们排序算法的时间复杂度。排序里,快排和堆排都是不错的选择,时间复杂度o(NlogN)
但是其实题目一并没有要求我们要把所有数据有序啊,直接粗暴对所有数据进行排肯定效率不是最佳。
既然只找第K大的数,我们只需找到最大的K个数中最小的数!
K个节点的小根堆的根结点,正好符合我们的要求。
至于如何确最大K个数,我们可以直接选取,给的数据的前K个数,建一个小根堆,从K+1个元素开始到最后一个元素,将它与前面排序最小的元素进行比较,如果小于,不做处理,大于的话,把它与最小的元素交换,重新排序。当所有元素处理过后,我们便得到一个有最大K个的小根堆,选取他们的最小值(根结点),题目便解决了。
按照我们上边的方法,我最多执行(N-K+1)次K个元素的堆排,时间复杂度o((N-K+1)logK),当N>>K的时候近似o(NlogK)
代码
建堆
2.选取第K大的数
运行结果:
:
题目一:寻找一组数据中第K大的数
分析:
题目描述很简单,完全可以将所有的数据从大到小进行排序,选取第K个数,便可以解决我们的问题,这样的话,时间复杂度就将取决于我们排序算法的时间复杂度。排序里,快排和堆排都是不错的选择,时间复杂度o(NlogN)
但是其实题目一并没有要求我们要把所有数据有序啊,直接粗暴对所有数据进行排肯定效率不是最佳。
既然只找第K大的数,我们只需找到最大的K个数中最小的数!
K个节点的小根堆的根结点,正好符合我们的要求。
至于如何确最大K个数,我们可以直接选取,给的数据的前K个数,建一个小根堆,从K+1个元素开始到最后一个元素,将它与前面排序最小的元素进行比较,如果小于,不做处理,大于的话,把它与最小的元素交换,重新排序。当所有元素处理过后,我们便得到一个有最大K个的小根堆,选取他们的最小值(根结点),题目便解决了。
按照我们上边的方法,我最多执行(N-K+1)次K个元素的堆排,时间复杂度o((N-K+1)logK),当N>>K的时候近似o(NlogK)
代码
建堆
//调整堆 template<typename ElemType> void AdjustHeap(ElemType *array,const int &index,int end) { bool flag = true; int temp; int begin = index; while (index-1+(begin-index+1)* 2 <= end&&flag) { if (array[begin] > array[begin * 2]) { temp = begin * 2; } else { temp = begin; } if (begin * 2 + 1 <= end) { if (array[begin * 2 + 1] <array[begin * 2]) { temp = begin * 2 + 1; } } if (begin == temp) { flag = false; } else { swap(array,begin, temp); begin = temp; } } } //建堆 template<typename ElemType> void CreateHeap(ElemType *array,const int &begin,const int &end) { int distance = end - begin; for (int i = begin + distance / 2+1; i >= begin; i--) { AdjustHeap(array,i,end); } } //交换数据 template<typename ElemType> void swap(ElemType *array, const int index1, const int index2) { array[index1] = array[index1] ^ array[index2]; array[index2] = array[index1] ^ array[index2]; array[index1] = array[index1] ^ array[index2]; }
2.选取第K大的数
#include "HeapSort2.0.h" #include <iostream> #include <cstdlib> /// 选取数据中第K大的数 /// @param elem 储存数据的数据指针 /// @param n 数据量 /// @param k 选取的第K大的数 /// @param begin 数据储存开始的索引 /// @return 第K大的数 template<typename ElemType> ElemType SelectKMaxNum(ElemType *elem,int n,int k,int begin) { CreateHeap(elem, begin, k+begin-1); for (int i = k + 1; i <= n; i++) { if (elem[begin] < elem[i]) swap(elem, begin, i); AdjustHeap(elem, begin, k); } return elem[begin]; } int main() { //数据开始的索引为1 int elem[11] = { 0,12,15,89,3,64,8,9,6,3,2 }; std::cout <<SelectKMaxNum(elem,10,3,1)<< std::endl; std::system("pause"); }
运行结果:
:
相关文章推荐
- 剑指offer系列-T24_2二叉搜索树的后序遍历序列
- 安装程序时出现2502 2503错误解决方法
- REDHAT6.5实现Nginx+Tomcat+Memcache负载均衡
- 两台主机网线直连
- 二、 JVM参数调试
- 水平垂直居中问题解法
- AndroidStudio使用SVN
- 一、 jvm运行机制
- hdu 1232 畅通工程并查集版
- Flume快速入门(五):File Channel之重播(replay)
- Memcached内存管理slabclass
- 【慢速学数据结构】集合(并查集)篇
- VS2013的 Browser Link 引起的问题
- C 语言 指针和数组的结合
- 正式开始博客之旅
- jenkins页面不刷新,设置tomcat缓存
- 2016阿里安全峰会:我一次思想排空的旅程
- java 集合中自定义对象的几种排序方法
- 第十一次课总结及作业
- 最大流,二分法,拆点法(士兵移动 uva 12264)