一步一步写算法(之挑选最大的n个数)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
从一堆数据中挑选n个最大的数,这个问题是网上流传的比较广的几个问题之一。具体来说,它的意思就是:假设我们有100个数据,我们需要挑选出最大的n个数据(n < 100),那么有没有办法实现这样一个目标呢?在这里,我想从排序的角度看看有没有什么办法可以实现这样一个目标。
在前面的博客当中,我们实现的排序算法有下面几种:
(2) 快速排序
(3) 合并排序
(4) 堆排序
(5)选择排序
(6) 基数排序
那么是不是这8种算法都适合今天的题目呢?我简单的对它们进行了分析和归类:
a)不到最后无法求出最大数据的算法,(插入算法,合并算法,基数排序)
这些算法的特点就是可以保证局部的数据基本有序,但是无法保证全局的数据有序。在全部数据得到正确地排序之前,没有人知道最大的数据是什么。所以针对这个题目而言,要想知道最大的n个数,那就等于要对所有的数据全部排序一遍。
b)每次求出一个最大的数据,依次类推,直到所有的数据都已经排序。(冒泡排序、希尔排序、选择排序、堆排序)
这些算法的特点就是,排序的时候,所有的数据都是按照从大到小排列出来的。按照冒泡排序来说,首先我们选出最大的数据,然后是第二大的数据,依次类推,直到第n大的数据找到为止。堆排序也是这样,我们在构建堆之后,也是每次从堆顶获得一个数据,不断调整堆,再接着获得第二大、第三大......第n大的数据的。我们以冒泡排序为例,看看这一次的算法应该怎么写?
- void find_n_max_number(int array[], int length, int number)
- {
- int inner ;
- int outer;
- int median;
- if(NULL == array || 0 == length)
- return;
- if(number > length)
- return;
- for(outer = length -1; outer > (length - 1 - number); outer --){
- for(inner = 0; inner < outer; inner ++){
- if(array[inner] > array[inner +1]){
- median = array[inner];
- array[inner] = array[inner + 1];
- array[inner + 1]= median;
- }
- }
- }
- }
c)迭代搜索,首先对数据进行分类,小于于数组第一个数据的排在左边,大于的排在右边。如果右边的数据小于n,为m,那么在左边数组继续寻找剩下的(n-m)个数据;如果右边的数据大于n,那么在右边的数据继续寻找。(快速排序)
不知道上面的解释说明白了没,没有清楚的同学可以看一看下面这个代码。
- int partion(int array[], int start, int end, int swap[])
- {
- int loop;
- int left = 0;
- int right = end - start;
- int value = array[start];
- for(loop = start +1; loop <= end; loop++){
- if(array[loop] < value)
- swap[left ++] = array[loop];
- else
- swap[right --] = array[loop];
- }
- swap[left] = value;
- memmove(&array[start], swap, sizeof(int) * (end - start +1));
- return left + start;
- }
- void _quick_sort(int array[], int start, int end, int swap[], int number)
- {
- int middle;
- if(start < end){
- middle = partion(array, start, end, swap);
- if((number - 1) > (end - middle))
- _quick_sort(array, start, middle -1, swap, number - (end - middle + 1));
- else
- _quick_sort(array, middle + 1, end, swap, number);
- }
- }
- void find_n_max_number(int array[], int length, int number)
- {
- int* swap ;
- if(NULL == array || 0 == length)
- return;
- swap = (int*)malloc(sizeof(int) * length);
- _quick_sort(array, 0, length-1, swap, number);
- free(swap);
- }
总结:
至于这些算法的结果怎么样,各位朋友们可以自己利用自己的电脑好好测试一下。
一步一步写算法(之挑选最大的n个数)的更多相关文章
- 一步一步写算法(之prim算法 中)
原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...
- 一步一步写算法(之prim算法 下)
原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...
- 一步一步写算法(之prim算法 上)
原文:一步一步写算法(之prim算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前面我们讨论了图的创建.添加.删除和保存等问题.今 ...
- 一步一步写算法(之n!中末尾零的个数统计)
原文:一步一步写算法(之n!中末尾零的个数统计) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 在很多面试的题目中,求n!结果中零的个数也是 ...
- 一步一步写平衡二叉树(AVL树)
平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...
- .NET跨平台:在Mac上跟着错误信息一步一步手写ASP.NET 5程序
今天坐高铁时尝试了一种学习ASP.NET 5的笨方法,从空文件夹开始,根据运行dnx . kestrel命令的错误信息,一步一步写代码,直至将一个最简单的ASP.NET程序运行起来. 尝试的具体步骤如 ...
- 一步一步理解Paxos算法
一步一步理解Paxos算法 背景 Paxos 算法是Lamport于1990年提出的一种基于消息传递的一致性算法.由于算法难以理解起初并没有引起人们的重视,使Lamport在八年后重新发表到 TOCS ...
- 《一步一步写嵌入式操作系统》读书笔记1—Skyeye介绍、安装和HelloWorld
2013-11-14 最近在看<一步一步写嵌入式操作系统>,感觉此书甚好,许多地方讲得很清楚.可操作性强,计划边读边实践边写笔记,希望能够逐步熟悉嵌入式操作系统底层的东西,最终剪裁出一套实 ...
- 一步一步写一个简单通用的makefile(三)
上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...
随机推荐
- Android供TextView添加多个点击文字
我们使用社会性软件的过程中会或多或少像别人的帖子点,图. : 能够看到用户页面显示出来的仅仅是点了赞的用户的名称,点击这些名称能够进入到该用户的主页.我们就来实现相似的效果.直接上代码吧. @Over ...
- java它 ------ 图形界面(两)
<img src="http://img.blog.csdn.net/20150604093446275?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi ...
- 朝花夕拾-4-shell
引言 shell,我们常常会用到,以其强大的功能,会帮助我们解决非常多棘手的问题.近期遇到一个问题,要跑非常多case,假设串行的执行,须要非常久.能不能让他们并行起来,但又不能全部case都并行执行 ...
- windows(64位)下用vagrant+virtualbox 管理虚拟机具体解释
windows下安装(64位) vagrant 跟 vituriebox http://blog.smdcn.net/article/1308.html Host: 127.0.0.1 Port: 2 ...
- android在当前app该文件下创建一个文件夹
/********************************************************************* * Author : Samson * Date ...
- POJ 2996 & 2993 国际象棋布局 模拟
Description Your task is to read a picture of a chessboard position and print it in the chess notati ...
- Javascipt数组去重的几种方式
方法一 function unique(arr) { var retArr = []; for (var i = 0; i < arr.length; i++) { (retArr.indexO ...
- Mybatis基金会: 经常问的问题FAQ
Mybatis基金会: #{...} 和 ${...} 差额 MyBatis将 #{-} 解释为JDBC prepared statement 参数标记.而将 ${-} 解释为一个字符串替换.非常实用 ...
- VisualStudio 怎么使用Visual Leak Detector
VisualStudio 怎么使用Visual Leak Detector 那么在Windows下有什么好的内存泄漏检测工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检测 ...
- 十天学Linux内核之第二天---进程
原文:十天学Linux内核之第二天---进程 都说这个主题不错,连我自己都觉得有点过大了,不过我想我还是得坚持下去,努力在有限的时间里学习到Linux内核的奥秘,也希望大家多指点,让我更有进步.今天讲 ...