排序算法的总结

来源:互联网 发布: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;

}

     

 

2 0
原创粉丝点击