| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2199 人关注过本帖
标题:从数组抽取前5位最大值,并按大小排序
只看楼主 加入收藏
google
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:22
帖 子:3419
专家分:23
注 册:2005-11-1
收藏
得分:0 
我觉得我那种方法要是10个数排序的话,冒泡+二分还可以,取前5个的话还是冒泡好些

祝天下所有母亲幸福安康!~
2007-03-26 14:00
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 

现成的函数吧(c++)


#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main()
{
int a[10]={1,4,7,3,5,2,10,6,7,9};
int max;
int i=0;
vector<int> array(a,a+10);
vector<int>::iterator it;
vector<int> order;
while(i++<5)
{
max=*max_element(array.begin(),array.end());
order.push_back(max);
it=find(array.begin(),array.end(),max);
array.erase(it,it+1);
}
sort(order.begin(),order.end());
for(i=0;i<5;++i) cout<<order[i]<<\" \";

return 0;
}


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2007-03-26 14:03
千里冰封
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:灌水之王
等 级:版主
威 望:155
帖 子:28477
专家分:59
注 册:2006-2-26
收藏
得分:0 
人才也,你搞起C++也是这么强

可惜不是你,陪我到最后
2007-03-26 14:06
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 
不好意思,刚才睡着了。刚看到你们的回帖。

首先是猴子的算法,这样做迭代了N次,效率比较低

冒泡的话,是最原始的算法,我说10个中抽5个只是比喻,如果从10亿个中抽5亿个

那如果先冒泡完10亿在抽前5亿个元素,那效率就……
2007-03-26 14:48
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 
阿姨的意思,我没懂
2007-03-26 14:54
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 
谢谢unicorn的,那个算法仍然是先排序,后取其中前5位的
2007-03-26 14:54
福尔摩斯
Rank: 5Rank: 5
等 级:贵宾
威 望:12
帖 子:4011
专家分:370
注 册:2006-8-15
收藏
得分:0 
以下是引用live41在2007-3-26 14:54:45的发言:
谢谢unicorn的,那个算法仍然是先排序,后取其中前5位的

我还是觉得我的算法是最好的

抽取的过程并排序


自我放逐。。。
2007-03-26 14:55
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 
以下是引用福尔摩斯在2007-3-26 13:36:54的发言:

觉得好玩,我把这种算法推广到 实数集 吧

按照 最大的5个数字(最小的也一样,5也是可以改的)

首先,先抽取最小数字(正负数都可以,如果抽最小的5个数字,就把最小数字改成最大数字就可以了),然后,在这个数-1,备用

第二步,抽取数组中最大的数字,在它的位子上替换上第一步的那个数字;如此循环做5次,就能得到你要的那5个数字(而且不要冒泡

你个bc,这就是二分法(快速排序)

2007-03-26 15:03
福尔摩斯
Rank: 5Rank: 5
等 级:贵宾
威 望:12
帖 子:4011
专家分:370
注 册:2006-8-15
收藏
得分:0 
以下是引用live41在2007-3-26 15:03:42的发言:

你个bc,这就是二分法(快速排序)

我这些词汇不会

我只知道怎么用,不知道叫什么


自我放逐。。。
2007-03-26 15:04
google
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:22
帖 子:3419
专家分:23
注 册:2005-11-1
收藏
得分:0 

排序算法是数据结构学科经典的内容,其中内部排序现有的算法有很多种,究竟各有什么特点呢?本文力图设计实现常用内部排序算法并进行比较。分别为起泡排序,直接插入排序,简单选择排序,快速排序,堆排序,针对关键字的比较次数和移动次数进行测试比较.

问题分析和总体设计

ADT OrderableList{
数据对象:D={ai| ai∈IntegerSet,i=1,2,…,n,n≥0}
数据关系:R1={〈ai-1,ai〉|ai-1, ai∈D, i=1,2,…,n}
基本操作:
InitList(n)
操作结果:构造一个长度为n,元素值依次为1,2,…,n的有序表。
Randomizel(d,isInverseOrser)
操作结果:随机打乱
BubbleSort( )
操作结果:进行起泡排序
InserSort( )
操作结果:进行插入排序
SelectSort( )
操作结果:进行选择排序
QuickSort( )
操作结果:进行快速排序
HeapSort( )
操作结果:进行堆排序
ListTraverse(visit( ))
操作结果:依次对L种的每个元素调用函数visit( )
}ADT OrderableList

待排序表的元素的关键字为整数.用正序,逆序和不同乱序程度的不同数据做测试比较,
对关键字的比较次数和移动次数(关键字交换计为3次移动)进行测试比较.
要求显示提示信息,用户由键盘输入待排序表的表长(100-1000)和不同测试数据的组数(8-18).每次测试完毕,要求列表现是比较结果.
要求对结果进行分析.

详细设计
1、起泡排序
算法:核心思想是扫描数据清单,寻找出现乱序的两个相邻的项目。当找到这两个项目后,交换项目的位置然后继续扫描。重复上面的操作直到所有的项目都按顺序排好

bubblesort(struct rec r[],int n)
{
int i,j;
struct rec w;
unsigned long int compare=0,move=0;
for(i=1;i<=n-1;i++)
for(j=n;j>=i+1;j--)
{
if(r[j].key<r[j-1].key)
{
w=r[j];
r[j]=r[j-1];
r[j-1]=w;
move=move+3;
}
compare++;
}
printf("
BubbleSort compare= %ld,move= %ld
",compare,move);
}


2、直接插入排序
算法:经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L[i]插入L[1..i-1]的适当位置,使得L[1..i]又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较L[i]和L[i-1],如果L[i-1]≤ L[i],则L[1..i]已排好序,第i遍处理就结束了;否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),使得L[j] ≤L[j+1]时为止

insertsort(struct rec r[],int n)
{
int i,j;
unsigned long int compare=0,move=0;
for(i=2;i<=n;i++)
{compare++;
r[0]=r[i];
move++;
j=i-1;
while(r[0].key {r[j+1]=r[j];
j--;
move++;
++compare;}
r[j+1]=r[0];
move++;
}
printf("
InsertSort compare= %ld,move= %ld
",compare,move);
}


3、简单选择排序
算法:首先找到数据清单中的最小的数据,然后将这个数据同第一个数据交换位置;接下来找第二小的数据,再将其同第二个数据交换位置,以此类推。

selectsort(struct rec r[],int n)
{
unsigned long int compare=0,move=0;
int i,j,k;
struct rec w;
for(i=1;i<=n-1;i++)
{ k=i;
for(j=i+1;j<=n;j++)

{ if(r[j].key>r[k].key) {k=j; compare++; }
w=r[i];
r[i]=r[k];
r[k]=w;
move=move+3;

}
}
printf("
SelectSort compare= %ld,move= %ld
",compare,move);
}


4、快速排序
算法:首先检查数据列表中的数据数,如果小于两个,则直接退出程序。如果有超过两个以上的数据,就选择一个分割点将数据分成两个部分,小于分割点的数据放在一组,其余的放在另一组,然后分别对两组数据排序。
通常分割点的数据是随机选取的。这样无论你的数据是否已被排列过,你所分割成的两个字列表的大小是差不多的。而只要两个子列表的大小差不多


q(struct rec r[],int s,int t)
{
int i=s,j=t;
if(s<t)
{
r[0]=r[s]; ++a; c++;
do{
while(j>i&&r[j].key>=r[0].key)
{j--;
++a; }
if(i<j)
{ r[i]=r[j];
i++;
c++; }
while(i<j&&r[i].key<=r[0].key)
{i++;
++a; }
if(i<j)
{ r[j]=r[i];
j--;
c++; }
} while(i<j);
r[i]=r[0];
c++;
q(r,s,j-1);
q(r,j+1,t);
}
}


5. 堆排序
(1) 基本思想:
堆排序是一树形选择排序,在排序过程中,将R[1..N]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。
(2) . 堆的定义: N个元素的序列K1,K2,K3,...,Kn.称为堆,当且仅当该序列满足特性:
Ki≤K2i Ki ≤K2i+1(1≤ I≤ [N/2])


sift(struct rec r[],int l,int m)
{
int i,j;
struct rec w;
i=l; j=2*i;
w=r[i];
while(j<=m)
{
if(j<m&&r[j].key<r[j+1].key) { j++;
}
if(w.key<r[j].key)
{
r[i]=r[j];
i=j;
j=2*i;
}
else j=m+1;
}
r[i]=w;
}

heapsort(struct rec r[],int n)
{
unsigned long int compare=-1,move=-1;
struct rec w;
int i;
int a;
for(i=n/2;i>=1;i--) a=sift(r,i,n);
compare++;
move++;

for(i=n;i>=2;i--)
{
w=r[i];
r[i]=r[1];
r[1]=w;
a=sift(r,1,i-1);
compare+=a;
move+=a;
}
}


小结:
1.学会使用随机函数randomize( ) 为数组赋初值要在头文件中添加#include
2.在做此程序之前基本上是在理解了各种排序过程以后完成的
3.对排序算法的总结:
(1)若n较小(如n≤50),可采用直接插入或直接选择排序。
 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。
(2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;
(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。
 快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
 堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。


该文章转载自网络大本营:http://www.pushad.com/Info/1124.Html


祝天下所有母亲幸福安康!~
2007-03-26 15:09
快速回复:从数组抽取前5位最大值,并按大小排序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.034519 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved