众所周知,Std::sort()是一个非常快速的排序算法,它基于快排,但又有所修改。一般来说用它就挺快的了,代码一行,时间复杂度O(nlogn)(难道不是大叫一声“老子要排序!!”就排好了么。。。)。我们也知道,不基于比较的排序可以达到O(n),比如说基数排序。什么,它是O(n
* log(10)( max(n) ) )
的?NO!!我们可以用sqrt(max(n))来作为进制,这样就是(N*logMax(n))=O(2*n)的了。。看起来很不错, 代码量嘛。。。。呵呵
所谓基数排序,就是做几次筒排,每一位一次,然后拉直,然后继续,时间复杂度O(n),我们来看一下效果吧
Data1:10^7随机数据
Data2:10^7不随机,从10^7到0
Data3:第二个数据每一项除与2,10^7项
Data4:第一个数据每一项除与2,10^7项
效果:
std::sort()
1.7.07s
2.5.51s
3.7.00s
4.5.31s
基数排序
1.5.31s
2.7.26s
3.4.89s
4.7.06s
觉得很奇怪,其实一四是对应的,二三是对应的。。。然后为什么会这样。。。不懂不懂。。。
分析一下,可能是读入原因,或者std::sort()对一些特殊的有优化,但是很大可能是——Cena抽了。。。
基数排序在排序上优化还是挺大的,但是,代码量和常数还有适用范围。。。呵呵
本文纯粹太无聊作死只做,我不会说std::sort()在评测的时候连续4次75分,每次无输出的点还不一样。。。Cena啊,你何时出1.0啊。。。
付:我写的基数排序极丑代码。。。
1 #include <cmath>
2 #include <iostream>
3 #include <cstdio>
4 #include <cstdlib>
5
6 using namespace std;
7 struct num
8 {
9 int data;
10 num* next;
11 }nu[100000000];
12
13 void plu(num *f,num *b)
14 {
15 f->next=b;
16 }
17
18 num* t[100000];
19 num* e[100000];
20 void add(int pos,num* l)
21 {
22 if (e[pos])
23 {
24 e[pos]->next=l;
25 e[pos]=l;
26 }
27 else
28 {
29 t[pos]=l;
30 e[pos]=l;
31 }
32 }
33
34 int predo()
35 {
36 int n,ret=0;
37 scanf("%d",&n);
38 for (int i=1;i<=n;++i)
39 {
40 int j;
41 scanf("%d",&j);
42 nu[i].data=j;
43 nu[i].next=nu+i+1;
44 if (i==n) nu[i].next=NULL;
45 ret=max(ret,j);
46 }
47 return ret;
48 }
49 num* root=nu+1;
50
51 void JSsort(int n)
52 {
53 for (num* now=root;now;)
54 {
55 num* nex=now->next;
56 now->next=NULL;
57 int tt=now->data%n;
58 add(tt,now);
59 now=nex;
60 }
61 num* last=NULL;
62 for (int i=0;i<n;++i)
63 {
64 if (t[i])
65 {
66 if (!last)
67 {
68 root=t[i];
69 }
70 else
71 {
72 last->next=t[i];
73 }
74 for (num *now=t[i];now;now=now->next)
75 last=now;
76 }
77 t[i]=e[i]=NULL;
78 }
79 for (num* now=root;now;)
80 {
81 num* nex=now->next;
82 now->next=NULL;
83 int tt=now->data/n;
84 add(tt,now);
85 now=nex;
86 }
87 last=NULL;
88 for (int i=0;i<n;++i)
89 {
90 if (t[i])
91 {
92 if (!last)
93 {
94 root=t[i];
95 }
96 else
97 {
98 last->next=t[i];
99 }
100 for (num *now=t[i];now;now=now->next)
101 last=now;
102 }
103 }
104 return;
105 }
106
107 void print()
108 {
109 for (num* now=root;now;now=now->next)
110 {
111 printf("%d ",now->data);
112 }
113 printf("\n");
114 return;
115 }
116
117 int main()
118 {
119 freopen ("sort.in","r",stdin);
120 freopen ("sort.out","w",stdout);
121 int k=predo();
122 JSsort(sqrt(k)+1);
123 print();
124 return 0;
125 }
非常无聊——STD::sort VS 基数排序,布布扣,bubuko.com
时间: 2024-10-11 01:32:13