排序算法:将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程
排序的方法有许多种,如:插入排序、希尔排序、冒泡排序、归并排序、选择排序......这些不同排序的排序算法,其中的原理也大不相同。
(小声哔哔:此篇博客中排序算法的定义参考了百度百科qwq......)
Part 1.按算法分类
Part 2.按时间复杂度分类
开始贴代码啦!
(PS:以下所列的排序算法均为从小到大排序)
为了使数据有小到大(升序)排列,在比较和交换的过程中,越小的数就会像气泡一样慢慢地“浮”到数列的顶端,所以把这种算法命名为“冒泡排序”。
冒泡排序 简易版(稳定)
#include<bits/stdc++.h> using namespace std; int a[1000001]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n-1;i++)//进行n-1轮比较 for(int j=1;j<=n-i;j++)//每轮比较n-i次 if(a[j]>a[j+1]) swap(a[j],a[j+1]);//比较大小,交换两数位置 for(int i=1;i<=n;i++) cout<<a[i]<<" "; }
如下这种改良版的冒泡排序只要排序完成就会推出序列,这种方式已经减少了时间的许多浪费。假设现有一个长度10000的数组,前1000无序,后9000有序并且大于前1000数据。用上面这种方法,数据交换次数在1000之内,但是剩下9000的数据虽然没有交换,但是每次循环都会进行比较。剩下9000数据已经有序了,我们不用对它们进行判断,浪费不必要的时间。
冒泡排序 改良版(稳定)
#include<bits/stdc++.h> using namespace std; int a[1000001]; bool f; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=n-1;i>=1;i--) { f=true;//bool类型变量f判断是否交换 for(int j=1;j<=i;j++) { if(a[j]>a[j+1]) { swap(a[j],a[j+1]); f=false; } } if(f==true) break; } for(int i=1;i<=n;i++) cout<<a[i]<<" "; }
基本思想:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。
插入排序(稳定)
#include<bits/stdc++.h> using namespace std; int a[1000001]; int main() { int n,temp,i,j,k; cin>>n; for(i=0;i<n;i++) cin>>a[i]; for(i=0;i<n;i++) { for(j=i-1;j>=0;j--) if(a[j]<a[i]) break;//找到比a[i]小的位置就退出,插在它后面 if(j!=i-1) { temp=a[i];//将比a[i]大的数向后移 for(k=i-1;k>j;k--) a[k+1]=a[k]; a[k+1]=temp; } } for(int i=0;i<n;i++) cout<<a[i]<<" "; }
桶排序 (Bucket sort)就是所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再进行个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间O(n)。但桶排序并不是比较排序,他不受到 O(n log n) 下限的影响。
桶排序(稳定)
#include<bits/stdc++.h> using namespace std; int a[1000001]; int main() { int n,k; cin>>n; for(int i=1;i<=n;i++) { cin>>k; a[k]++; } for(int i=0;i<=1000000;i++) { while(a[i]>0) { cout<<i<<" "; a[i]--;//输出一个整数后,个数减一 } } }
基本思想:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2 =1(dt,dt-1...
希尔排序(不稳定)
#include<bits/stdc++.h> using namespace std; int a[1000001]; int main() { int n,k,j; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; int gap=n/2; while(gap>0) { for(int i=gap+1;i<=n;i++) { j=i; while(j-gap>0&&a[j]<a[j-gap]) { swap(a[j],a[j-gap]); j=j-gap; } } gap=gap/2; } for(int i=1;i<=n;i++) cout<<a[i]<<" "; }
快速排序是冒泡排序的一种改进算法。它也是通过不断地比较和移动交换来实现排序,只不过它的实现增大了记录的比较和移动的距离,将关键字较大的元素从前面直接放到后面,关键字较小的元素直接从后面放到前面,从而减小了比较次数和交换次数。
快速排序(不稳定)
#include<bits/stdc++.h> using namespace std; int a[10000001]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n); for(int i=1;i<=n;i++) cout<<a[i]<<" "; }
基本思想:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。
选择排序(不稳定)
#include<bits/stdc++.h> using namespace std; int a[1000001]; int main() { int n,k; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; for(int i=0;i<n;i++) { k=i;//选最小的元素a[k] for(int j=i+1;j<n;j++) if(a[j]<a[k]) k=j; if(k!=i)//交换a[i]和a[k],将现在的最小值放在a[i]的位置上 swap(a[i],a[k]); } for(int i=0;i<n;i++) cout<<a[i]<<" "; }
结束啦!撒个花!
看在我这么努力的份上,请我喝杯奶茶鸭!
QQ赞赏
微信赞赏
PS:记得给我留下你认为励志与美的句子哦~嘻嘻!