排序总结(C语言)

排序是很基础的东西了,本篇文章总结了一下常用的排序方法,选择排序,插入排序,冒泡排序,归并排序,快速排序。

前面三种排序算法效率都比较低,时间复杂度都是O(n²)

选择排序法
选择排序是从N个待排序的数中找到最小的数,放到第0个位置上,然后再从剩下的N-1个数里找到最小的,放到第1个位置上……,直到所有元素排好序。

void selectionsort(int a[],int size) //选择排序法
{
    int i,j,min,swap;
    for(i=0;i<size-1;i++){
            min=i;
    for(j=i+1;j<size;j++){
        if(a[j]<a[min]){
            min=j;
        }
    swap=a[i];
            a[i]=a[min];
            a[min]=swap;
    }}
    for(int i=0;i<size;i++){
           cout<<a[i];
           cout<<" ";
    }

}

插入排序法

  • 插入排序法是将待排序的数组分为有序和无序两部分,前者在左边,后者在右边。
  • 开始时有序数组只有a[0]一个元素,其余都属于无序部分
  • 每次取出无序部分的第一个元素,插入到有序部分,假设插入到合适的位置p,则原p位置及其后面的有序部分元素都要依次向右移动一个位子,有序部分即增加了一个元素。
  • 直到无序部分没有元素
void insertationsort(int a[],int size) //插入排序
{
    int i,j,temp;
    for(i=1;i<size;i++){//i为无序数组的第一个元素
            for(j=0;j<i;j++){
                    //找到a[i]的合适位置
                if(a[j]>a[i]){
                        temp=a[i];
            //a[i]及后面有序部分元素依次右移
                    for(int k=i;k>j;k--){
                        a[k]=a[k-1];
                    }
                    a[j]=temp;
                    break;
                }
            }
    }
    for(int i=0;i<size;i++){
       cout<<a[i];
       cout<<" ";
    }
}

冒泡排序法

  • 冒泡排序法也是将待排序的算法分为有序和无序的两部分,前者在右,后者在左。
  • 刚开始整个数组都是无序部分,有序部分没有元素。
  • 每次要使得无序部分最大的元素移动到有序部分第一个元素的左边。移动的方法是:依次比较相邻的两个元素,如果前面的比后面的大,就交换他们的位置。这样,大的元素就像水里的气泡一样不断往上浮。移动结束,有序部分就增加了一个元素。
  • 直到无序部分没有元素。
    下面是代码实现
void bubblesort(int a[],int size)
    {
        for(int i=0;i<size-1;i++)
        for(int j=0;j<size-i;j++){
            if(a[j]>a[j+1]){
                int tmp=a[j];
                a[j]=a[j+1];
                a[j+1]=tmp;
            }
        }
        for(int i=0;i<size;i++){
            cout<<a[i]<<" ";
        }
    }

下面两种排序法的时间复杂度均为O(nlogn)

归并排序

  • 把前一部分排序
  • 把后一部分排序
  • 把两半归并到一个新的有序数组里,然后再拷贝回原数组
void Merge(int a[],int s,int m,int e,int tmp[])
{//a[]是待排序数组,tmp[]是临时存放的空数组
    //s是待排序部分数组起始下标,m是中间下标,e是结束下标
    int pb=0;
    int p1=s,p2=m+1;
    //将s到m,m+1到s两部分按大小顺序归并到tmp数组里
    while(p1<=m&&p2<=e){
        if(a[p1]<a[p2])
            tmp[pb++]=a[p1++];
            else
                tmp[pb++]=a[p2++];
    }
    //两部分剩下的部分依次存到tmp数组里
    while(p1<=m)
        tmp[pb++]=a[p1++];
    while(p2<=e)
        tmp[pb++]=a[p2++];
    for(int i=0;i<e-s+1;i++){
        a[s+i]=tmp[i];
    }
}
void Mergesort(int a[],int s,int e,int tmp[])
{
    if(s<e){
    int m=s+(e-s)/2;
    Mergesort(a,s,m,tmp);
    Mergesort(a,m+1,e,tmp);
    Merge(a,s,m,e,tmp);
    }
}

快速排序

  • 设k=a[0],将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k右边,和k相等的,不关心在k左右出现均可。
  • 把k左边的部分快速排序
  • 把k右边的部分快速排序
void swap(int &a,int &b)
{
    int tmp=a;
    a=b;
    b=tmp;
}
void Quicksort(int a[],int s,int e)
{//a[]为待排序数组,s为待排序部分起始下标,e为结束下标
    if(s>=e)
        return;
    int k=a[s];
    int i=s,j=e;
    while(i!=j){
        while(a[j]>=k&&i<j)
            j--;
        swap(a[i],a[j]);
        while(a[i]<=k&&i<j)
            i++;
        swap(a[i],a[j]);
    }
    Quicksort(a,s,i-1);
    Quicksort(a,i+1,e);
}

猜你喜欢

转载自blog.csdn.net/qq_40980884/article/details/83180837
今日推荐