一道算法题:从1000万个整数中选出1000个最大的数

flamingheart 2005-10-14 09:38:17
请问应该怎么做,最好的算法复杂度是多少?
...全文
1784 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
无心人 2005-12-12
  • 打赏
  • 举报
回复
效率好的插入算法的描述的而已
skys712 2005-12-12
  • 打赏
  • 举报
回复
算法上限应该是NLOG(N)
Cybergate 2005-11-25
  • 打赏
  • 举报
回复
试验结果出来了。性能:

Partial Quicksort(部分快排)>弹出堆顶1000个 >>> 平衡二叉树

这三个方法在C++ STL里都有实现。

平衡二叉树是实践中最差的方法,主要在于旋转带来的性能折扣。
blooney 2005-11-25
  • 打赏
  • 举报
回复
不过确实楼上几个好几个星星的算法不好的
blooney 2005-11-25
  • 打赏
  • 举报
回复
嘿嘿,原来我对大家解法的评论,怎么没了?是不是说的太直接被斑竹删了啊?
nipcdll 2005-11-22
  • 打赏
  • 举报
回复
mark
mayunshui 2005-11-22
  • 打赏
  • 举报
回复
我想到一个算法,不知如何
一遍循环就求出
oo 2005-11-21
  • 打赏
  • 举报
回复
对1000个有序元素的数组的查找虽然能log1000,但插入新数据时数据的移动是1000/2的时间的。
sdhp 2005-11-21
  • 打赏
  • 举报
回复
我的方法:
维护一个1000个有序元素的数组,遍历1000万数据,将大于数组中最小元素的数据插入到有序数组中(使用折半查找)

理由:
1不使用平衡二叉排序树:因为插入数据需要重新平衡
2不使用分组冒泡:该方法将许多不需要排序的数据都进行了排序
其他方法还没有考虑(正在研究堆排序)

结果:
PIII 500M,192M 的机器用时6秒(包括读数据文件,不包括数据输出)
2004csharp 2005-11-21
  • 打赏
  • 举报
回复
堆排:
void AdjustHeap(int arr[],int low,int high)
{
a[0]=a[low];
for(int j=2*low;j<=high;j=j*2;)
if(a[j+1]>a[j] && j+1<high) j=j+1;
if(a[j]<=a[0]) break;
int temp=a[j/2];a[j/2]=a[j];a[j]=temp;a[0]=a[j];

}
void HeapSort(int arr[],int low,int high)
{
for(long i=high/2;i>low;i--)
AdjustSort(arr,i,high)
a[low]^=a[high]; a[high]^=a[low]; a[low]^=a[high];
int num=1;

while(num<1000)
{
high=high-num;
AdjustSort(arr,i,high)
a[low]^=a[high]; a[high]^=a[low]; a[low]^=a[high];
num++;
}
}
Kvci 2005-11-21
  • 打赏
  • 举报
回复
要不要考虑空间啊?
如果不考虑空间(即空间可以无限大)
或许有什么特殊办法吧
2004csharp 2005-11-21
  • 打赏
  • 举报
回复

一种快排:我觉得性能还可以
void QuickSort(int arr[],int low,int high)
{
int m=partion(arr,low,high); //注意:这里倒序,即m前的全比arr[m]大,m后的
全比arr[m]小
QuickSort(arr,low,m-1);
if(m<1000)
QuickSort(arr,low,m-1);

}
Major_C 2005-11-19
  • 打赏
  • 举报
回复
还想请问诸位:
如何用c++在windows系统中对一个进程/线程的cpu时间和使用内存数进行读取?
盼高手现身指教!
Major_C 2005-11-19
  • 打赏
  • 举报
回复
因为ln10000000=16<1000,所以全排序算法中这里使用O(NlnN)的算法比较合适
但是,由于这道题仅要求从10000000个数中找出前1000来,所以容易知道任何使整个数列全部有序的方法必然是浪费和低效的
楼上的方法是正解,速度比传统的快排和堆排更快,只不过分组数还可以改进。如果设分成n组,每组m个数的话,可知比较次数约等于10000000+1000(n+m),这里n*m恒等于10^7。

另外,我想问一下,在全排序算法中,为什么大家都不用基数排序( O(n*d)级 )呢?
高手指教!
114sky 2005-11-18
  • 打赏
  • 举报
回复
void quick(int *a,int i,int j)
{
int m,n,temp;
int k;
m=i;
n=j;
k=a[(i+j)/2]; /*选取的参照*/
do {
while(a[m]<k&&m<j) m++; /* 从左到右找比k大的元素*/
while(a[n]>k&&n>i) n--; /* 从右到左找比k小的元素*/
if(m<=n) { /*若找到且满足条件,则交换*/
temp=a[m];
a[m]=a[n];
a[n]=temp;
m++;
n--;
}
}while(m<=n);
if(m<j) quick(a,m,j); /*运用递归*/
if(n>i) quick(a,i,n);
}
oo 2005-11-18
  • 打赏
  • 举报
回复
分1000组,每组1万个。
对每组冒泡一次,得出每组最大的。

最冒泡出的1000个冒泡一次,得出最大的,输出;
对输出的最大数所在的组做一次冒泡;

重复上一步1000次,就可以了。
oo 2005-11-18
  • 打赏
  • 举报
回复
ft,写错了。
是:冒泡法可以做到 2*1000万 + 1000*1000
sdhp 2005-11-18
  • 打赏
  • 举报
回复
我觉得关键问题不是在排序算法上,试想1000万个4字节的数据就是40M左右,一般来说不可能一次都Load到内存中,所以考虑到磁盘读的速度和内存度速度的差异因该尽量减少1000万数据的遍历,所以二叉排序数理论上来说要快一点
Cantonese00 2005-11-18
  • 打赏
  • 举报
回复
楼上的来个快速排序?

最大堆排序最差就达到 O(nlgn),
快速排序也能达到O(nlgn),最差是O(n^2),是不稳定。

分段处理可能会好点,或许是几个算法的综合...

个人比较赞同xiaocai0001的说法
Mr_Yang 2005-11-17
  • 打赏
  • 举报
回复
学习。
加载更多回复(18)

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧