【竞赛】排序算法的最快实现

老紫竹 2008-06-23 02:14:12
规则如下:
1 数据量为10万(好的算法可以到100万),从小到大排序
2 数据采用如下代码产生,保证测试数据的唯一性
3 不限制内存的使用
4 最后将在不同用户的同一台机器上进行多次测试,以运行时间为标准,越少越好。
5 如果速度太快,就使用 System.nanoTime(); 进行判断或者加大数据量到100万,甚至1000万数量级进行判断。
6 评委暂定为java版的几位小版主

参加方法
1 直接把代码回复在后面即可
2 截至日期为本周5的晚上
3 奖励前5名,第一名400技术专家分,第二名200技术专家分,3、4、5名每人100技术专家分。
4 前2名,允许个人介绍,求职,个人作品宣传的帖子大版置顶3天。

初始化代码如下。
import java.util.Random;

class T {
public static void main(String[] args) {
int MAX = 100000;
int[] nums = new int[MAX];
Random r = new Random(20080623);
for (int i = 0; i < MAX; i++) {
nums[i] = r.nextInt(MAX);
}
long begin = System.currentTimeMillis();
sort(nums);
long end = System.currentTimeMillis();
System.out.println((end - begin)); // 以这个时间为标准,越小越好。
}

public static int[] sort(int[] nums) {
// 您的排序代码放在这里啦
return nums;
}
}
...全文
3389 202 打赏 收藏 转发到动态 举报
写回复
用AI写文章
202 条回复
切换为时间正序
请发表友善的回复…
发表回复
LQC87573510 2012-01-09
  • 打赏
  • 举报
回复
我擦 细细读完 大狼神的回帖 果然犀利的一比,再次膜拜
nply2008 2008-07-02
  • 打赏
  • 举报
回复
这么多,看晕掉,等待总结... ...
lhy011 2008-06-27
  • 打赏
  • 举报
回复
temp[nums[i++]]++;
这句有问题
lwptianzi 2008-06-27
  • 打赏
  • 举报
回复
弱人,来学习一下,等待结贴
zhuyx808 2008-06-27
  • 打赏
  • 举报
回复
马克~
aaronyy2002 2008-06-27
  • 打赏
  • 举报
回复
等总结贴!
niat97222 2008-06-26
  • 打赏
  • 举报
回复
来晚了,来一个自己想的赖皮算法
运行最快是31毫秒,跑出来的最慢是78毫秒

public static int[] sort(int[] nums) {
class sortObj{
int m_num;
int m_size;

sortObj(int num){
m_num=num;
m_size = 1;
}

int getNum(){return m_num;}
int getSize(){return m_size;}

void incObj(){m_size++;};
}

int max = getMax(nums);
int[] rslt = new int[nums.length];
sortObj[] objLst = new sortObj[max+1];
for (int i=0;i<nums.length;i++){
sortObj sort= null;

try{
sort = objLst[nums[i]];
} catch (Exception er){
System.out.println("max="+max);
System.out.println("i="+i);
System.out.println("nums[i]="+nums[i]);
}


if (sort==null){
sort = new sortObj(nums[i]);
} else {sort.incObj();}
objLst[nums[i]]=sort;
}

int j=0;
for (int i=1;i<objLst.length;i++){
if (objLst[i]!=null){
for (int k=0;k<objLst[i].getSize();k++){
rslt[j]=objLst[i].getNum();
j++;
}
}
if (j>=nums.length) {break;}
}


return rslt;
}

public static int getMax(int[] nums){
int max = nums[0];
for (int i:nums){
max = max>nums[i]?max:nums[i];
}
return max;
}

ppx3200 2008-06-25
  • 打赏
  • 举报
回复
[Quote=引用 185 楼 superdullwolf 的回复:]
千万数据:2172ms
我还是比这个大师快一个数量级。
看来,我跟随的大师比这个大师要牛叉一些。
[/Quote]

兄弟,你的桶式排序在内存有限又或者最大范围不是20080623而是20080623000000时,桶式算法根本不能解决问题。
再说,要是需要排序的整数只有几千个时,你浪费内存的情况下无法估计的。桶式算法是牺牲内存来换取速度上的优势。
虽然快,但未必是最好的算法。
所以,你鄙视别人没有是没有道理的
超级大笨狼 2008-06-25
  • 打赏
  • 举报
回复
如果范围是10万、100万、1000万,输入也是10万、100万、1000万数据,只有脑残才会这么出题目。

按照这个范围,我的代码速度是100万数据78毫秒,1000万750毫秒
超级大笨狼 2008-06-25
  • 打赏
  • 举报
回复
楼上傻叉,鉴定完毕。

如果按照10万、100万、1000万个桶的范围计算,我的代码速度就会更快。
你需要吸收的是排序的理论和思路,而不是具体的语言。



interpb 2008-06-24
  • 打赏
  • 举报
回复
[Quote=引用 185 楼 superdullwolf 的回复:]
千万数据:2172ms
我还是比这个大师快一个数量级。
看来,我跟随的大师比这个大师要牛叉一些。
[/Quote]

确实很牛叉 但是空间换时间的代价也太大了吧

人家大师 用内存没你用的好
超级大笨狼 2008-06-24
  • 打赏
  • 举报
回复
千万数据:2172ms
我还是比这个大师快一个数量级。
看来,我跟随的大师比这个大师要牛叉一些。
scf37 2008-06-24
  • 打赏
  • 举报
回复
仔细想想,发现John sheep的这个算法已经出奇的好了。。。
shibenjie 2008-06-24
  • 打赏
  • 举报
回复

import java.util.Random;

public class QuickSort {

/**
* create date:2008-6-24 author:smilewater
*
* @param args
*/
public static void main(String[] args) {
int MAX = 100000;
int[] nums = new int[MAX];

Random r = new Random(20080623);
for (int i = 0; i < MAX; i++) {
nums[i] = r.nextInt(MAX);
}

long begin = System.currentTimeMillis();
// Arrays.sort(nums);
sort1(nums, 0, nums.length);
long end = System.currentTimeMillis();
System.out.println((end - begin)); // 以这个时间为标准,越小越好。
}

/**
* Swaps x[a] with x[b].
*/
private static void swap(int x[], int a, int b) {
int t = x[a];
x[a] = x[b];
x[b] = t;
}

/**
* Returns the index of the median of the three indexed integers.
*/
private static int med3(int x[], int a, int b, int c) {
return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a)
: (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}

/**
* Sorts the specified sub-array of integers into ascending order.
*/
private static void sort1(int x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i = off; i < len + off; i++)
for (int j = i; j > off && x[j - 1] > x[j]; j--)
swap(x, j, j - 1);
return;
}

// Choose a partition element, v
int m = off + (len >> 1); // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len / 8;
l = med3(x, l, l + s, l + 2 * s);
m = med3(x, m - s, m, m + s);
n = med3(x, n - 2 * s, n - s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
int v = x[m];

// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while (true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}

// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a - off, b - a);
vecswap(x, off, b - s, s);
s = Math.min(d - c, n - d - 1);
vecswap(x, b, n - s, s);

// Recursively sort non-partition-elements
if ((s = b - a) > 1)
sort1(x, off, s);
if ((s = d - c) > 1)
sort1(x, n - s, s);
}

/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(int x[], int a, int b, int n) {
for (int i = 0; i < n; i++, a++, b++)
swap(x, a, b);
}

}

大师的源码运行速度
十万数据:15 ms
百万数据:188ms
千万数据:2172ms
zhenxi_he 2008-06-24
  • 打赏
  • 举报
回复
sort_sagezk2= 117224116 0 1248 23498 67876 999999
sort_scf37= 117857716 0 1248 23498 67876 999999
sort_roofalison= 124729539 0 1248 23498 67876 999999
sort_john_sheep= 144508869 0 1248 23498 67876 999999
sort_lwouyang= 145016475 0 1248 23498 67876 999999
sort_joneyonly3= 292130704 0 1248 23498 67876 999999
qSor_hmsuccess= 329151610 0 1248 23498 67876 999999
sort_preferme= 333201846 0 1248 23498 67876 999999
sort_JDK= 344957250 0 1248 23498 67876 999999
sort_OXFORD_216= 350317149 0 1224 27373 69355 999999
sort_B_Lee2= 358643906 0 1248 23498 67876 999999
sort_J_Factory= 371528504 0 1248 23498 67876 999999
sort_sagezk= 372204848 0 1248 23498 67876 999999
sort_talent_marquis= 392380038 0 1248 23498 67876 999999
quickSort_jdlsfl= 413720459 0 1248 23498 67876 999999
sort_joneyonly2= 451753505 0 1248 23498 67876 999999
sort_hmsuccess2= 531078670 417157 975013 397974 608759 371602
sort_geyunfei_hit= 713468611 0 1248 23498 67876 999999
sort_joneyonly= 1121522149 0 1248 23498 67876 999999
sort_aunty_flybird= 1209051150 0 1248 23498 67876 999999
scf37 2008-06-24
  • 打赏
  • 举报
回复
我又很无聊的修改了sagezk的。。。

public static int[] sort(int[] nums) {
int max = nums.length;
int i, j;
int[] temp = new int[max];
for (i = 0; i < max;) {
temp[nums[i++]]++;
}
int pos = 0;
for (i = 0; i < max; ++i) {
for (j = 0; j < temp[i]; ++j) {
nums[pos++] = i;
}
}
return nums;
}


超级大笨狼 2008-06-24
  • 打赏
  • 举报
回复
10万需要187毫秒
100万需要250毫秒
1000万需要984毫秒

请拿出比这个好于一个数量级的结果来。

我代表C#版来拿第一行不?
超级大笨狼 2008-06-24
  • 打赏
  • 举报
回复
闻道有先后,树业有专攻。
被鄙视不要紧,缺啥补啥,建议看看《算法导论》,先吸取前人的成果,我敢鄙视你是因为我站在巨人的肩膀上。
鄙视是客观的,即使我不鄙视你,也会有人鄙视你。

看看下边的东东,就知道了,鄙视其实是轻微的,在ACM国际比赛中失败才是真正丢脸的事情。


一般要做到50行以内的程序不用调试、100行以内的二分钟内调试成功.acm主要是考算法的
,主要时间是花在思考算法上,不是花在写程序与debug上。
下面给个计划你练练:

第一阶段:
练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,
因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打
出来.
1.最短路(Floyd、Dijstra,BellmanFord)
2.最小生成树(先写个prim,kruscal要用并查集,不好写)
3.大数(高精度)加减乘除
4.二分查找. (代码可在五行以内)
5.叉乘、判线段相交、然后写个凸包.
6.BFS、DFS,同时熟练hash表(要熟,要灵活,代码要简)
7.数学上的有:辗转相除(两行内),线段交点、多角形面积公式.
8. 调用系统的qsort, 技巧很多,慢慢掌握.
9. 任意进制间的转换

第二阶段:
练习复杂一点,但也较常用的算法。
如:
1. 二分图匹配(匈牙利),最小路径覆盖
2. 网络流,最小费用流。
3. 线段树.
4. 并查集。
5. 熟悉动态规划的各个典型:LCS、最长递增子串、三角剖分、记忆化dp
6.博弈类算法。博弈树,二进制法等。
7.最大团,最大独立集。
8.判断点在多边形内。
9. 差分约束系统.
10. 双向广度搜索、A*算法,最小耗散优先.

第三阶段:
前两个阶段是打基础,第三阶段是锻炼在比赛中可以快速建立模型、想新算法
。这就要平时多做做综合的题型了。
1. 把oibh上的论文看看(大概几百篇的,我只看了一点点,呵呵)。
2. 平时扫扫zoj上的难题啦,别老做那些不用想的题.(中大acm的版主经常说我挑简单的来
做:-P )
3. 多参加网上的比赛,感受一下比赛的气氛,评估自己的实力.
4. 一道题不要过了就算,问一下人,有更好的算法也打一下。
5. 做过的题要记好 :-)

kuyesuifeng 2008-06-24
  • 打赏
  • 举报
回复
我晕,来晚了,我来晚了!!!!!!!!!
超级大笨狼 2008-06-24
  • 打赏
  • 举报
回复
理论上,任何排序都可以在时间复杂度为O(n),空间复杂度为O(1)。
加载更多回复(180)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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