前言
要活动更好的阅读体验,戳我
最近,我美化了我的blog
.但是文章很少,为了避免华而不实 (就是因为我懒) ,我决定从今天开始更文啦~
(安利一个链接)
想用迅雷下载?
https://crab-in-the-northeast.github.io/downloads/all_sorts_code.zip
声明:本篇文章为东北小蟹蟹原创,部分图片从百度百科搬来。转载不用跟我说,但请附上原文地址。
阅读本文你需要:
1.有一个对编程良好的态度
2.对事物有好奇心
3.会C++基础语法
背景
三年之后……
突然,一个螃蟹找到了我。
他自称他叫“小排”,然后领我带到了一个隧道,
有一个紧锁的门。门上写着:
1,4,5,6,8,2,8.
上面有一个牌子,写着“谁要是通过了这个隧道,就可以获得无价之宝”。
右边是一台迷你计算机,左面的墙壁写了一个很大的"sort".
我顿时明白了,原来是让我们编辑代码来把数字排序啊!
门上还刻有一行英文:
You can't use the same kinds of sorts in two or more levels.
(每一关都要用不同种类的排序)
于是,我便和小伙伴踏上了冒险之路。。。。
(ps
:不要管螃蟹是怎么打字的)
冒险开始了!
基于数值的排序 number
计数排序 counting sort
概念 conception
“这怎么办?” 小排抱怨。
我沉默不语,在沙滩下画上了8
个格子。
小排好奇地瞅着我,问道:“这是什么意思呀?”
“你看,牌子上的数组是1,4,5,6,8,2,8
吧。”
“嗯嗯。”
“这些格子的初始值都是0
哈,首先来访的是1
,所以我把第一个格子的数值+1
.”
“嗯。这个时候8
个格子分别为1,0,0,0,0,0,0,0
了。”
“然后又来了4
,所以我们把第四个……”
他迫不及待地把第四个格子里填了1
.看来他还是挺聪明的。
他也不把用来写字的树枝还给我。不过我很开心,因为他明白了。
“可是到达第7
个数,8
已经是1
了,怎么搞?”
“那你就再+1
呗。”
于是,格子里的数字分别是
“1,1,0,1,1,1,0,2
”
“所以你到底要干甚?”
“你想想看~”
他深思熟虑了片刻。你也思考思考吧~答案请往下翻。
|
|
|
S
l
i
d
e
d
o
w
n
t
o
s
e
e
n
e
x
t
p
a
g
e
!
|
|
|
他顿时大雾悟,明白了OI能让人掉多少头发。
“我们只要从第一个格子开始遍历,然后输出这个格子所对应的值次的下标,就可以排序了!”
“bingo!这就是计数排序,完美~”
这里我再解释一下:
现在我们有了8
个格子。
刚才说过格子里的数字分别是
“1,1,0,1,1,1,0,2
”
第一个,值是1,下标是1
,所以输出1
次1
,输出了1
第二个,值是1,下标是2
,所以输出1
次2
,输出了2
第三个,值是0,下标是3
,不输出
第四个,值是1,下标是4
,所以输出1
次4
,输出了4
第五个,值是1,下标是5
,所以输出1
次5
,输出了5
第六个,值是1,下标是6
,所以输出1
次6
,输出了6
第七个,值是0,下标是7
,不输出
第八个,值是2,下标是8
,所以输出2
次8
,输出了8 8
尤其是 第八个 要格外小心。
所以输出了1 2 4 5 6 8 8
.
哇,这是我们学习的第一个排序算法,干杯~
代码 code
代码就很显然了,如下:
#include <iostream>
#include <cstdio>
using namespace std;
int a[10005];//假设数列中最大值为10000,防爆+5.
int n;
int main()
{
cin>>n; //一共有多少个数?
for(int i=0;i<n;i++)
{
int k;
cin>>k;//输入当前的值
a[k]++;//对应位置自增
}
for(int i=0;i<=10005;i++)
if(a[i])//如果存在这个数
for(int j=1;j<=a[i];j++)//输出多少次呢?
cout<<i<<' ';//输出这个数
return 0;
}
练习 practicing
再实现一次倒序。
提示:很简单,倒着遍历就行了~
分析 analysis
这个算法的正确性毋庸置疑,那么复杂度呢?
我们设k为数组中的最大值。
时间复杂度 是O(n+k)
,时间复杂度较低。
空间复杂度 也是O(k)
,那么这是优点还是缺点?留个悬念,一会讲。
果然,小排知道了计数排序的优点之后,就觉得计数排序无敌了!
计数排序是很好,因为 时间复杂度 很低。
但是没有任意一个算法是无敌的,OI
算法的水深,他不被淹是不知道的。
所以,我考验他一下,
还是排序。数列变成了这样:
-2122,9.990,2147483646,13131314,123456789,-123123123
真是极品数据233
果然他又哭着找我了,说我欺负它。
原因嘛你懂得,不懂你模拟一下就有bug
了。
顺便说一下,这个排序算法是稳定排序。
“东北小蟹蟹,什么是稳定排序啊?”
“如果原数列有两个值是一样的,并且排序后,这两个值的相邻关系一定不变,就是一开始排序的两个等值谁在前谁在后,排序后一定还是那个在前的在前,在后的在后,那么这个排序就是稳定排序,如果不能保证这个关系,则是不稳定排序。由于,你把数扔进对应的格子里,计数器+1,则从前往后遍历,一定顺序不变。所以,这个排序是稳定排序。并且我们要注意不稳定指的是未知,有可能还是原来的顺序,