非常无聊——STD::sort VS 基数排序

  众所周知,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

非常无聊——STD::sort VS 基数排序的相关文章

std::sort 学习:一种递归分治方法

// std::sort 学习:一种递归分治方法 今天看了看 stl 的 std::sort 的代码,众所周知,这个函数是在快速排序递归太深的时候使用堆排序防止过度退化,但是今天说的不是这个.我们只看快速排序的部分. 我们一般实现快速排序大概是这样的(本王随意写了个用下标当参数的排序函数,领会意思即可). void quick_sort(int first, int last) // 某个数组的 [first, last) {  if ((last - first) > 1) {  int mi

源码阅读笔记 - 1 MSVC2015中的std::sort

大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格式化,去掉或者展开用于条件编译或者debug检查的宏,依重要程度重新排序函数,但是不会改变命名方式(虽然MSVC的STL命名实在是我不能接受的那种),对于代码块的解释会在代码块前(上面)用注释标明. template<class _RanIt, class _Diff, class _Pr> in

std::sort要求strict weak ordering

strict weak ordering简单地说就是小于语义,非小于等于语义,也就是说对于相等的或者异常的元素比较应当返回false 后果很严重,在google搜一下violating strict weak ordering make std::sort crash能看到很多种后果, 经测试,当待排序元素大于16个时使用std::sort,若传入的callable违反strict weak ordering,则可能死循环也可能越界访问. 待排序元素小于等于16个不会有问题是因为std::sor

测试std::sort 和std::qsort 的性能, 修改编译器栈大小

根据effective STL中Item 46 提到, C程序员很难接受C++的STL中std::sort(定义于头文件<algorithm>)竟然比C语言的std::qsort(定义与头文件<cstdlib>中)快了670%. 最后Scot Meyer建议我们我们要使用C++的std::sort函数. 我们知道qsort 实现的排序算法是快排, 但是std::sort 实现的排序算法并不知道, 有人说这得看是哪一个STL版本了. std::sort的大部分实现的是quick so

[C/C++标准库]_[初级]_[使用std::sort排序各种类型数据]

std::sort 场景: 1. 在使用sort排序时,有时候需要对对象的某个值进行排序,比如对类对象的某个id的int类型值或者bool类型值,其实bool类型值排序研究了半天.. test_sort.cpp #include <stdlib.h> #include <string.h> #include <string> #include <vector> #include <algorithm> #include <iostream&

将三维空间的点按照座标排序(兼谈为std::sort写compare function的注意事项)

最近碰到这样一个问题:我们从文件里读入了一组三维空间的点,其中有些点的X,Y,Z座标只存在微小的差别,远小于我们后续数据处理的精度,可以认为它们是重复的.所以我们要把这些重复的点去掉.因为数据量不大,这里不准备使用划分包围盒或者建立k-d tree这样的重型武器,我们简单的把点按照其三维坐标进行排序就好. 我们准备使用STL的std::sort来做这个排序.它要求提供一个符合如下签名的比较函数: bool cmp(const Type1 &a, const Type2 &b) 怎么样写这个

std::sort()

原文地址:http://blog.csdn.net/factor2000/article/details/3936195 1 #include "stdafx.h" 2 #include <vector> 3 #include <algorithm> 4 #include <functional> 5 #include <iostream> 6 7 using namespace std; 8 9 //Return whether fir

GDB实践:一场std::sort引发的coredump

以前只掌握gdb一些基础知识,还没有真正"实战"过.刚好最近同事一个进程coredump了,原因比较深,正好利用这个机会来分析下 // @ 运行:gdb [可执行程序] -c [coredump文件] gdb edu_info_recommend_svr -c core_edu_info_recomm // @ 查看堆栈信息:bt (backtrace) (gdb) bt 10 #0 0x00007fa0809b6144 in __strcmp_sse42 () from /lib64

std::sort的详细用法

1 #include <algorithm> 2 #include <functional> 3 #include <array> 4 #include <iostream> 5 6 int main() 7 { 8 std::array<int, 10> s = { 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 }; 9 10 // sort using the default operator< 11 std::sort(s