一步一步写算法(之挑选最大的n个数)
2014-04-11 19:17
211 查看
原贴地址: http://blog.csdn.net/feixiaoxing/article/details/6882510
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
从一堆数据中挑选n个最大的数,这个问题是网上流传的比较广的几个问题之一。具体来说,它的意思就是:假设我们有100个数据,我们需要挑选出最大的n个数据(n < 100),那么有没有办法实现这样一个目标呢?在这里,我想从排序的角度看看有没有什么办法可以实现这样一个目标。
在前面的博客当中,我们实现的排序算法有下面几种:
(1) 冒泡排序、插入排序、希尔排序
(2) 快速排序
(3) 合并排序
(4) 堆排序
(5) 选择排序
(6) 基数排序
那么是不是这8种算法都适合今天的题目呢?我简单的对它们进行了分析和归类:
a)不到最后无法求出最大数据的算法,(插入算法,合并算法,基数排序)
这些算法的特点就是可以保证局部的数据基本有序,但是无法保证全局的数据有序。在全部数据得到正确地排序之前,没有人知道最大的数据是什么。所以针对这个题目而言,要想知道最大的n个数,那就等于要对所有的数据全部排序一遍。
b)每次求出一个最大的数据,依次类推,直到所有的数据都已经排序。(冒泡排序、希尔排序、选择排序、堆排序)
这些算法的特点就是,排序的时候,所有的数据都是按照从大到小排列出来的。按照冒泡排序来说,首先我们选出最大的数据,然后是第二大的数据,依次类推,直到第n大的数据找到为止。堆排序也是这样,我们在构建堆之后,也是每次从堆顶获得一个数据,不断调整堆,再接着获得第二大、第三大......第n大的数据的。我们以冒泡排序为例,看看这一次的算法应该怎么写?
[cpp] view
plaincopy
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,那么在右边的数据继续寻找。(快速排序)
不知道上面的解释说明白了没,没有清楚的同学可以看一看下面这个代码。
[cpp] view
plaincopy
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);
}
总结:
至于这些算法的结果怎么样,各位朋友们可以自己利用自己的电脑好好测试一下。
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
从一堆数据中挑选n个最大的数,这个问题是网上流传的比较广的几个问题之一。具体来说,它的意思就是:假设我们有100个数据,我们需要挑选出最大的n个数据(n < 100),那么有没有办法实现这样一个目标呢?在这里,我想从排序的角度看看有没有什么办法可以实现这样一个目标。
在前面的博客当中,我们实现的排序算法有下面几种:
(1) 冒泡排序、插入排序、希尔排序
(2) 快速排序
(3) 合并排序
(4) 堆排序
(5) 选择排序
(6) 基数排序
那么是不是这8种算法都适合今天的题目呢?我简单的对它们进行了分析和归类:
a)不到最后无法求出最大数据的算法,(插入算法,合并算法,基数排序)
这些算法的特点就是可以保证局部的数据基本有序,但是无法保证全局的数据有序。在全部数据得到正确地排序之前,没有人知道最大的数据是什么。所以针对这个题目而言,要想知道最大的n个数,那就等于要对所有的数据全部排序一遍。
b)每次求出一个最大的数据,依次类推,直到所有的数据都已经排序。(冒泡排序、希尔排序、选择排序、堆排序)
这些算法的特点就是,排序的时候,所有的数据都是按照从大到小排列出来的。按照冒泡排序来说,首先我们选出最大的数据,然后是第二大的数据,依次类推,直到第n大的数据找到为止。堆排序也是这样,我们在构建堆之后,也是每次从堆顶获得一个数据,不断调整堆,再接着获得第二大、第三大......第n大的数据的。我们以冒泡排序为例,看看这一次的算法应该怎么写?
[cpp] view
plaincopy
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,那么在右边的数据继续寻找。(快速排序)
不知道上面的解释说明白了没,没有清楚的同学可以看一看下面这个代码。
[cpp] view
plaincopy
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个数)
- 一步一步写算法(之挑选最大的n个数)
- 一步一步写算法(之 最大公约数、最小公倍数)
- 一步一步写算法(之 最大公约数、最小公倍数)
- 一步一步写算法(之 最大公约数、最小公倍数)
- 一步一步写算法(之 最大公约数、最小公倍数)
- 教你一步一步用c语言实现sift算法…
- 一步一步写算法(之查找)
- 整型数组处理算法(四)求数组的最大值和最小值
- HDU 2768 Cat vs. Dog 最大独立集+匈牙利算法(提高题)
- 【算法】图论_网络流_最大流
- 蓝桥杯 算法提高 算法提高 最大乘积
- (NYoj 237)游戏高手的烦恼 --二部图最大匹配,匈牙利算法
- 蓝桥杯 算法训练 最大最小公倍数
- 二叉查找树的查找,插入,最大/最小值查找,前驱/后续查找,删除算法[java]
- 算法题-从包含n个元素的无序列表中取出和最大的连续子集
- 数组基本算法(最大值,最小值,总和,平均数,复制,反转,排序)
- 一步一步写算法(如何判断一个素数和一段素数)
- 2.分治算法研究-搜索数组中的最大连续子集和 2014-3-11 11:37 阅读(16)
- 常见算法:C语言求最小公倍数和最大公约数三种算法