基于Visual C++2013拆解世界五百强面试题--题10-找出N个数种最大的K个数
来源:互联网 发布:二维数组的几种定义 编辑:程序博客网 时间:2024/06/04 04:19
有一亿个整数,请找出最大的 1000 个,要求时间越短越好, 空间占用越好越好。
如果不考虑时间效率,很容易想到解决方法,我们只需存储前一千个数,
然后依次读入后面的数和这一千个数组比较,替换其中比较小的数即可,
但是这样时间复杂度比较高,如果用二叉堆实现,直接可以替换1000个数中最小的数字,
而消耗的时间大多数话费在二叉堆插入中,二叉堆的插入复杂度为Olog(N),比较理想。
由于题目中数目太大,代码实现中是用户不停输入数字,然后程序找出前十个最大的数。
下面我们来实现它:
#include <stdio.h> //这个函数调整对数组中第n个元素的位置void HeapAdjust(int array[], int n, int length){int Child;for (int i = n; i * 2 <= length; i = Child){Child = i * 2;if (Child + 1 <= length && array[Child] < array[Child + 1])Child++;//如果较大的子节点大于父节点则交换位置if (array[i] < array[Child]){int Temp = array[i];array[i] = array[Child];array[Child] = Temp;}else{break;}}}void HeapSort(int array[], int length){//调整前半部分,保证了最大的值都在前半部分for (int i = length / 2; i > 0; i--){HeapAdjust(array, i, length);}for (int i = length-1; i > 0; i--){//将最大的数移动到尾部int Temp = array[1];array[1] = array[i+1];array[i+1] = Temp;//除去尾部后,调整第一个元素位置HeapAdjust(array, 1, i);}}void HeapAdjustLittle(int array[], int num, int length){//如果输入的数小于这些数,直接返回if (num < array[1]){return;}//如果输入的数大于数组中最小的数,则赋值,然后调整堆数组array[1] = num;int Child;for (int i = 1; i * 2 <= length; i = Child){Child = i * 2;if (Child + 1 <= length && array[Child] > array[Child + 1])Child++;//如果较小的子节点大于父节点则交换位置if (array[i] > array[Child]){int Temp = array[i];array[i] = array[Child];array[Child] = Temp;}else{break;}}}//打印出数组内容void PrintArray(int array[], int size){printf("最大的前%d个数:\n", size);for (int i = 0; i < size; i++){printf("%3d", array[i]);}printf("\n");}int myarray[] = { 0, 1, 9, 2, 8, 3, 7, 4, 6, 5 , 10};int main(){//将前十个数进行一次堆排序,并输出结果HeapSort(myarray, sizeof(myarray) / 4 - 1);PrintArray(myarray + 1, sizeof(myarray) / 4 - 1);//输入数字,打印出前十个最大的数while (1){int num = 0;scanf("%d", &num);HeapAdjustLittle(myarray, num, sizeof(myarray) / 4 - 1);PrintArray(myarray + 1, sizeof(myarray) / 4 - 1);}return 0;}
运行结果:
大家可以通过调试程序更好的理解程序运行,
将光标移至函数头,然后按下F9,打一个断点,按下F5程序即停止在断点处,如下图所示:
现在我们可以按F10单步调试,或者F11(可以跟进函数)。在调试窗口中看每一个变量的改变:
如果有什么问题和疑问可以在下面留言互相探讨。
原题我已经上传到这里了http://download.csdn.net/detail/yincheng01/6461073 ,
解压密码为 c.itcast.cn
- 基于Visual C++2013拆解世界五百强面试题--题10-找出N个数种最大的K个数
- 基于Visual C++2013拆解世界五百强面试题--题9-找出所有的排列方式
- 基于Visual C++2013拆解世界五百强面试题--题13-找最大公共子字符串
- 基于Visual C++2013拆解世界五百强面试题--题1-定义各种类型指针
- 基于Visual C++2013拆解世界五百强面试题--题3-打印螺旋数组
- 基于Visual C++2013拆解世界五百强面试题--题4-double转换成字符串
- 基于Visual C++2013拆解世界五百强面试题--题5-自己实现strstr
- 基于Visual C++2013拆解世界五百强面试题--题6-double类型逆序
- 基于Visual C++2013拆解世界五百强面试题--题11-查找数字出现次数
- 基于Visual C++2013拆解世界五百强面试题--题12-进制转换
- 基于Visual C++2013拆解世界五百强面试题--题14-循环删除
- 基于Visual C++2013拆解世界五百强面试题--题15-递归相加
- 基于Visual C++2013拆解世界五百强面试题--题16-进制分析
- 基于Visual C++2013拆解世界五百强面试题--题17-程序结果分析1
- 基于Visual C++2013拆解世界五百强面试题--题1-定义各种类型指针
- 基于Visual C++2013拆解世界五百强面试题--题7-链表的各种操作
- 基于Visual C++2013拆解世界五百强面试题--题8-数组的排序和查找
- 基于Visual C++2013拆解世界五百强面试题--题18-程序结果分析2-终结篇
- 检查及设置合理的undo表空间
- 关于loadrunner录制脚本不弹出浏览器问题
- 深度解析cocostudio是如何处理动作编辑器导出来的Json文件(2) (转)
- TOJ 2196 ZOJ 1423 (Your)((Term)((Project))) 字符串处理
- sql server 有关进程的操作
- 基于Visual C++2013拆解世界五百强面试题--题10-找出N个数种最大的K个数
- 判断二维矩阵中是否存在连续四个相同的数
- ORA-00265: 要求实例恢复, 无法设置 ARCHIVELOG 模式
- 设计模式(c++)笔记之十七(Memento模式)
- 上机项目--菜单的选择
- OCP-1Z0-053-V12.02-535题
- GDB 使用与示例
- [互联网面试笔试汇总C/C++-22] 拷贝构造函数调用的时机-完美世界
- Notepad源码分析