目录
一.选择排序
定义
性质
稳定性
时间复杂度
代码实现
二.冒泡排序
定义
过程
性质
稳定性
时间复杂度
代码实现
三.插入排序
定义
性质
稳定性
时间复杂度
代码实现
四.计数排序
定义
过程
计算前缀和的原因
性质
稳定性
时间复杂度
代码实现
五.基数排序
定义
过程
性质
稳定性
时间复杂度
空间复杂度
算法实现
今天我们开始排序算法的学习,本篇文章主要讲述选择排序,插入排序,冒泡排序,计数排序,基数排序.
其他五个排序算法太low了,这里就不细讲了.(主要是因为我不会)
选择排序(英语:Selection sort)是一种简单直观的排序算法。它的工作原理是每次找出第小的元素(也就是
中最小的元素),然后将这个元素与数组第
个位置上的元素交换。
由于 swap(交换两个元素)操作的存在,选择排序是一种不稳定的排序算法。
选择排序的最优时间复杂度、平均时间复杂度和最坏时间复杂度均为 。
void selection_sort(int* a,int n){for(int i=1;i
冒泡排序(英语:Bubble sort)是一种简单的排序算法。由于在算法的执行过程中,较小的元素像是气泡般慢慢「浮」到数列的顶端,故叫做冒泡排序。
它的工作原理是每次检查相邻两个元素,如果前面的元素与后面的元素满足给定的排序条件,就将相邻两个元素交换。当没有相邻的元素需要交换时,排序就完成了。
经过i次扫描后,数列的末尾i项必然是最大的i项,因此冒泡排序最多需要扫描n-1遍数组就能完成排序。
冒泡排序是一种稳定的排序算法。
在序列完全有序时,冒泡排序只需遍历一遍数组,不用执行任何交换操作,时间复杂度为 。
在最坏情况下,冒泡排序要执行(n-1)*n/2次交换操作,时间复杂度为 。
冒泡排序的平均时间复杂度为 。
void bubble_sort(int *a,int n){bool flag=true;while(flag){flag=false;for(int i=1;ia[i+1]){flag=true;int t=a[i];a[i]=a[i+1];a[i+1]=t;}}}
}
本页面将简要介绍插入排序。
插入排序(英语:Insertion sort)是一种简单直观的排序算法。它的工作原理为将待排列元素划分为「已排序」和「未排序」两部分,每次从「未排序的」元素中选择一个插入到「已排序的」元素中的正确位置。
一个与插入排序相同的操作是打扑克牌时,从牌桌上抓一张牌,按牌面大小插到手牌后,再抓下一张牌。
插入排序是一种稳定的排序算法。
插入排序的最优时间复杂度为 ,在数列几乎有序时效率很高。
插入排序的最坏时间复杂度和平均时间复杂度都为 。
void insertion_sort(int* a,int n){for(int i=2;i<=n;++i){int key=a[i];int j=i-1;while(j>0&&a[j]>key){a[j+1]=a[j];--j;}a[j+1]=key;}
}
Warning
本页面要介绍的不是基数排序
计数排序(英语:Counting sort)是一种线性时间的排序算法。
计数排序的工作原理是使用一个额外的数组C ,其中第i个元素是待排序数组 A中值等于i 的元素的个数,然后根据数组C来将A中的元素排到正确的位置。
它的工作过程分为三个步骤:
阅读本章内容只需要了解前缀和概念即可
直接将C中正数对应的元素依次放入A中不能解决元素重复的情形。
我们通过为额外数组C中的每一项计算前缀和,结合每一项的数值,就可以为重复元素确定一个唯一排名:
额外数组C中每一项的数值即是该 key 值下重复元素的个数,而该项的前缀和即是排在最后一个的重复元素的排名。
如果按照A的逆序进行排列,那么显然排序后的数组将保持A的原序(相同 key 值情况下),也即得到一种稳定的排序算法。
计数排序是一种稳定的排序算法。
计数排序的时间复杂度为 ,其中w代表待排序数据的值域大小。
const int N=100010;
const int W=100010;
int n,w,a[N],cnt[W],b[N];
void counting_sort(){memset(cnt,0,sizeof(cnt));for(int i=1;i<=n;++i) ++cnt[a[i]];for(int i=1;i<=w;++i) cnt[i]+=cnt[i-1];for(int i=n;i>=1;--i) b[cnt[a[i]]--]=a[i];
}
基数排序(英语:Radix sort)是一种非比较型的排序算法,最早用于解决卡片排序的问题。
基数排序的工作原理是将待排序的元素拆分为k个关键字(比较两个元素时,先比较第一关键字,如果相同再比较第二关键字……),然后先对第 k关键字进行稳定排序,再对第k-1关键字进行稳定排序,再对第k-2关键字进行稳定排序……最后对第一关键字进行稳定排序,这样就完成了对整个待排序序列的稳定排序。
基数排序是一种稳定的排序算法。
一般来说,如果每个关键字的值域都不大,就可以使用 计数排序 作为内层排序,此时的复杂度为 ,其中
为第i关键字的值域大小。如果关键字值域很大,就可以直接使用基于比较的
排序而无需使用基数排序了。
基数排序的空间复杂度为 。
const int N=100010;
const int W=100010;
const int K=100;
int n,w[K],k,cnt[W];
struct Element{int key[K];bool operator<(const Element& y)const{for(int i=1;i<=k;++i){if(key[i]==y.key[i])continue;return key[i]=1;--i) b[cnt[a[i].key[p]]--]=a[i];memcpy(a,b,sizeof(a));
}
void radix_sort(){for(int i=k;i>=1;--i){counting_sort(i);}
}
本来已经准备好的动图他突然传不上来了,只好在baike.baidu.com上面寻找(复制).所以对于萌新来说比较难理解(我就是萌新).
上一篇:【100个 Unity实用技能】 | Unity自定义脚本的初始模版
下一篇: 转岗申请书