排序算法的总结
来源:互联网 发布:centos安装sftp 编辑:程序博客网 时间:2024/05/18 13:25
1计数排序
一开始学排序算法想必就是用的计数排序话不多说直接上代码
复杂度最低的排序算法,稳定排序,O(n+m),n为元素个数,m为数值范围。在范围小的时候可以采用
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define M 1000005
using namespacestd;
int cnt[M];
int main(){
int n,a;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a;
cnt[a]++;
}
for(int i=0;i<=100004;i++){
if(cnt[i]){
for(intj=1;j<=cnt[i];j++)cout<<i<<" ";
}
}
return 0;
}
2
选择排序
也是最开始接触排序算法时学的代码如下
不稳定算法 复杂度O(n^2)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define M 1000005
using namespacestd;
int A[M];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>A[i];
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(A[j]<A[i]){
int t=A[i];
A[i]=A[j];
A[j]=t;
}
}
}
for(inti=1;i<=n;i++)cout<<A[i]<<" ";
return 0;
}
3.冒泡排序
很有意思的排序具体见代码
稳定排序,复杂度O(n^2),最好情况下O(n),冒泡排序发生的交换次数等于逆序对数。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define M 1000005
using namespacestd;
int A[M];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>A[i];
for(int i=1;i<=n;i++){//每一次操作都将最大的数送到最后的位置
bool f=0;
for(int j=1;j<=n-i;j++){
if(A[j]>A[j+1]){
int t=A[j];
A[j]=A[j+1];
A[j+1]=t;
f=1;
}
}
if(!f)break;//如果没有经过冒泡说明已经有序
}
for(inti=1;i<=n;i++)cout<<A[i]<<" ";
return 0;
}
4.插入排序
很形象的一个排序 将一个数插入进去其他位置下标往后挪 是一个稳定的排序算法复杂度最坏O(n^2)最好O(n)
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define M 1000005
using namespacestd;
int A[M];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>A[i];
for(int i=1;i<=n;i++){
int x=A[i];
int j;
// //[1,i-1]已经有序,把x插入进去
for(j=i-1;j>=1&&x<A[j];j--)
A[j+1]=A[j];//比x大的数往后挪
A[j+1]=x;//插入x
}
for(inti=1;i<=n;i++)cout<<A[i]<<" ";
return 0;
}
5.基数排序
很好理解的一个排序算法 因为这是按照位来比较
假如有5个数
12 57 100 29 33
先比较个位排序 100 012 013 057 029
在比较十位排序 100 012 013 029 057
最后比较百位 012013 029 057 100
得出答案12 13 29 57 100 是不是很好理解
注意数值需要判负数可以加上一个很大的数 然后再比较大小
复杂度O(n*m)m为最高位的长度
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define M 1000005
using namespacestd;
int A[M];
int s[10][M];
int main(){
int n,i,j,k;
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%d",&A[i]);
int len[10],d=1;
for(i=0;i<10;i++){
for(j=0;j<10;j++)len[j]=0;
for(j=0;j<n;j++){
k=A[j]/d%10;//第i位上的数值
s[k][len[k]++]=A[j];
}
int m=0;
for(j=0;j<10;j++){//按第i位依次排序
for(k=0;k<len[j];k++)
A[m++]=s[j][k];
}
d*=10;//继续判断下一位
}
for(i=0;i<n;i++)printf("%d",A[i]);
return 0;
}
6.归并排序 很重要的一种排序算法体现了一个很重要的思想 分治思想 分治即分而至
序列1 2 4 7 3 5 9 8
可以劈成两半 各自内部进行排序之后再合并起来
复杂度为稳定的O(nlogn)稳定排序
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define M 100005
using namespacestd;
int A[M],B[M];
void merge(intL,int R){//主函数调动merge(1,n)
if(L==R)return;//如果只有一个数自然不用劈成两半
int mid=(L+R)>>1;
merge(L,mid);.//左边继续归并
merge(mid+1,R);//右边继续
int i=L,j=mid+1,k=L;
while(i<=mid&&j<=R){
if(A[i]<A[j])B[k++]=A[i++];
else B[k++]=A[j++];
}
while(i<=mid)B[k++]=A[i++];
while(j<=R)B[k++]=A[j++];
for(int k1=L;k1<=R;k1++)A[k1]=B[k1];//将B数组重新合并赋值给A
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>A[i];
merge(1,n);
for(inti=1;i<=n;i++)cout<<A[i]<<" ";
return 0;
}
7.堆排序
堆是一种完全二叉树 只要构造一个堆满足小顶堆(即父亲节点的值大于两个儿子节点的值) 每次取出堆顶部的数然后继续组成一个堆就可以完全排序
复杂度O(nlogn)不稳定
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define M 100005
using namespacestd;
int heap[M],n,sz;
void swap(int&a,int &b){
int t=a;a=b;b=t;
}
void down(int x){
int t;
while(x<=sz){
int k1=x*2,k2=x*2+1;
if(heap[x]>heap[k1]&&k1<=sz){
t=k1;
}else t=x;
if(heap[t]>heap[k2]&&k2<=sz){
t=k2;
}
if(t!=x){
swap(heap[x],heap[t]);
x=t;
}else break;
}
}
void pop(){
cout<<heap[1]<<"";//输出堆顶最小的
heap[1]=heap[sz];//用堆最后的那个数覆盖第一个
sz--;
down(1);//down一下继续构造一个小顶堆
}
int main(){
cin>>n;
sz=n;
for(inti=1;i<=n;i++)cin>>heap[i];
for(int i=n/2;i>=1;i--)down(i);
for(int i=1;i<=n;i++)pop();
return 0;
}
8.关于希尔排序我也不是特别了解 就不作介绍了
快速排序也是一个极为重要的排序算法
以至于系统都有库函数 包含在头文件#include<algorithm>中
可以直接调用
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define M 100005
using namespacestd;
int A[M],n;
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>A[i];
sort(A+1,A+n+1);
for(inti=1;i<=n;i++)cout<<A[i]<<" ";
return 0;
}
好了 排完了是不是很快好吧我就是开个玩笑 然并卵 不了解使用原理 在noip2016初赛中 我惨烈的挂在快速排序上 平时都用sort调用原理都没弄懂 让我手敲sort直接懵逼了
快速排序的基本思想:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。然后再递归对这两部分进行排序。而这个数据的选择很有考究可以使用rand随机选取一个数据这样可以优化算法
不稳定的排序,平均复杂度是O(nlogn),最坏情况O(n^2)(有序数组)。
扩展用法:求序列中第K大数。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<time.h>
#define M 100005
using namespacestd;
int s[M],n;
void sort(intL,int R){
int low=L,high=R;
int key=s[low];//当然可以用rand大法造key值 在此我选择第一个数
while(low<high){
while(low<high&&key<=s[high])high--;//滑动右边指针
if(low<high)s[low]=s[high];
while(low<high&&key>=s[low])low++;//滑动右边指针
if(low<high)s[high]=s[low];
}
s[low]=key;//此时low与high相同
if(L<low-1)sort(L,low-1);//递归排序左区间
if(low+1<R)sort(low+1,R);//递归排序右区间
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>s[i];
sort(1,n);
for(inti=1;i<=n;i++)cout<<s[i]<<" ";
return 0;
}
- 排序算法的总结
- 排序算法的总结
- 排序算法的总结
- 排序算法的总结
- 排序算法的总结
- 排序算法的总结
- 排序算法的总结
- 一些排序算法的总结
- 排序算法的分类总结
- 简单排序算法的总结
- 排序算法的一些总结
- 整理的排序算法总结
- 排序算法的简单总结
- 排序算法的分析总结
- 各种排序算法的总结
- 各种排序算法的总结
- 各类排序算法的总结
- 常见的排序算法总结
- 使用protobuf和socket实现服务器间消息的传递
- Android布局实现圆角边框
- 遇到的警告以及解决方案
- servlet--days2
- 【自考】软件开发工具
- 排序算法的总结
- Linux安全设置
- asm训练(纯小白文高手勿看)
- Java熟悉到陌生之线程之Thread
- Oralce GoldenGate与Kafka集群集成
- 报数去除集合中的元素
- Leetcode 14 Longest Common Prefix
- SSL Certificate[Let's Encrypt]
- linux文件操作