一步一步写算法(之挑选最大的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 ...
随机推荐
- jquery经常使用事件(整理)
Jquery事件 (一).事件列表. 1.blur() 当失去焦点时触发.包含鼠标点击离开和TAB键离开. 2.change() 当元素获取焦点后,值改变失去焦点事触发. 3.click() 当鼠标单 ...
- 探索static——不需要能够使用该类实例?
在一般情况下.需要使用一个上课时间.你必须先实例化类,它调用的能力.在编程过程中发现.有些类不能直接实例来使用,利用其场.法等等. 这时候.靠的就是static作用.static英文意思为" ...
- DotNetOpenAuth实践
DotNetOpenAuth实践之搭建验证服务器 DotNetOpenAuth是OAuth2的.net版本,利用DotNetOpenAuth我们可以轻松的搭建OAuth2验证服务器,不废话,下面我们来 ...
- linux下各种文件格式的压缩以及解压缩命令
From : http://blog.csdn.net/mu0206mu/article/details/17732857 -------------------------------------- ...
- whu oj 1551 Pairs (莫队算法)
problem_id=1551">题目链接 题目大意: 给出的询问,求出这个区间的里 差小于等于 2 的数字的对数. 思路分析: 莫队算法. 然后分析一下. 假设添加了一个数字.那么就 ...
- 看多csdn它还烂论坛?
什么? 版权声明:本文博主原创文章,博客,未经同意不得转载.
- CIC and Fir 滤波器的级联
在FDATool中 CIC 和 Fir 级联滤波器的设计 1 设计CIC滤波器的幅频特性曲线如下 2.设计FIR 滤波器的幅频特性曲线如下 3.总的特性曲线如下 4.把通带部分放大后的图,比较平坦
- UVa753/POJ1087_A Plug for UNIX(网络流最大流)(小白书图论专题)
解题报告 题意: n个插头m个设备k种转换器.求有多少设备无法插入. 思路: 定义源点和汇点,源点和设备相连,容量为1. 汇点和插头相连,容量也为1. 插头和设备相连,容量也为1. 可转换插头相连,容 ...
- Oracle中的delete和truncate的关系
转自:http://chenxy.blog.51cto.com/729966/168459 1.相同点 a.都可以删除数据,其中truncate用于全表清空数据,而delete可以选择的删 ...
- Java变量参数
Java1.5添加新功能:可变参数:它适用于参数不确定性的数量,判断形势的类型.java变量参数数组操作. 特点: 1.今天的参数列表只能持续. 2.省略号(...)位于变量类型和变量名之间,前后有无 ...