排序算法总结

#排序算法总结
在这里插入图片描述

  1. 插入排序
    特点:效率低,容易实现
    原理:将数组分为两部分,将后部分元素逐一插入前部分有序元素的适当位置
void insert(int *a,int length);
int main() {
    int a[]={3,2,1,6,5,4,9,8,7,10};
    insert(a,10);
    for(int i=0;i<10;i++)
        cout<<a[i];
    return 0;
}
void insert(int *a,int length){
    int temp;
    for(int i=0;i<length;i++)
    {
        int j=i;
        temp=a[i];
        while(j>0&&temp<a[j-1])
        {
            a[j]=a[j-1];
            j--;
        }
        a[j]=temp;
    }
}
  1. 选择排序
    特点:效率低,容易实现
    原理:每一趟都将一个数排在序列左边的合适位置上,剩下的未排序序列,重复上述过程。
    优化方法:不用一遇到比已选择的元素大的元素就进行交换;而是记录该元素下标,最终只需要将该下标元素和需交换的元素交换即可。
void XuanZe(int *a,int length);
int main() {
    int a[]={3,2,1,6,5,4,9,8,7,10};
    XuanZe(a,10);
    for(int i=0;i<10;i++)
        cout<<a[i];
    return 0;
}
void XuanZe(int *a,int length){
    int index;
    for(int i=0;i<length-1;i++)
    {
        index=i;
        for(int j=i+1;j<length;j++)
            if(a[index]>a[j])
            {
                swap(index,j);
            }
        if(index!=i)
        {
            swap(a[index],a[i]);
        }
    }
}
  1. 冒泡排序
    特点:效率低,容易实现
    原理:将待排序列中最大的数往后冒泡,成为新的序列
for(i=0;i<n;i++)
    for(j=0;j<n-i-1;j++)
  1. 快速排序
    特点:高效,时间复杂度为nlogn;
    原理:采用分治法的思想:首先设置一个中间值,然后以这个中间值为划分基准将待排序序列分成比该值小的两部分,将这两部分再分别进行快速排序,直到序列只剩下一个元素。
void quicksort(int a[],int low,int high);
//快速排序
int main() {
    int a[]={4,3,2,1,5,8,7,6,10,9};
    quicksort(a,0,9);
    for(int i : a)
        cout<<i<<endl;
    return 0;
}
void quicksort(int *a,int low,int high){
    if(low<high)
    {
        int x=a[low],i=low,j=high;
        while(i<j)
        {
            while(i<j&&a[j]>=x)
                j--;
            if(i<j)
                a[i++]=a[j];
            while(i<j&&a[i]<=x)
                i++;
            if(i<j)
                a[j--]=a[i];
        }
        a[i]=x;
        quicksort(a,low,i-1);
        quicksort(a,i+1,high);
    }

}
  1. 归并排序
    核心思想:分治。

下面我们来看归并排序的思路(先讲思路再来具体讲归并的细节):

归并排序(Merge Sort)
在这里插入图片描述

当我们要排序这样一个数组的时候,归并排序法首先将这个数组分成一半。如图:
在这里插入图片描述

然后想办法把左边的数组给排序,右边的数组给排序,之后呢再将它们归并起来。当然了当我们对左边的数组和右边的素组进行排序的时候,再分别将左边的数组和右边的数组分成一半,然后对每一个部分先排序,再归并。如图:
在这里插入图片描述

对于上面的每一个部分呢,我们依然是先将他们分半,再归并,如图:
在这里插入图片描述

分到一定细度的时候,每一个部分就只有一个元素了,那么我们此时不用排序,对他们进行一次简单的归并就好了。如图:
在这里插入图片描述

归并到上一个层级之后继续归并,归并到更高的层级,如图:
在这里插入图片描述

直至最后归并完成。
在这里插入图片描述

void Merge(int r[],int r1[],int s,int m,int t) //r[]是一个输入的数组,r1[]是中间数组,s=0,t=数组长度减一
{
    int i=s;
    int j=m+1;
    int k=s;
    while(i<=m&&j<=t)
    {
        if(r[i]<=r[j])
            r1[k++]=r[i++];
        else
            r1[k++]=r[j++];
    }
    while(i<=m)
        r1[k++]=r[i++];
    while(j<=t)
        r1[k++]=r[j++];
    for(int l=0; l<8; l++)
        r[l]=r1[l];
}
 
void MergeSort(int r[],int r1[],int s,int t)
{
    if(s==t)
        return;
    else
    {
        int m=(s+t)/2;
        MergeSort(r,r1,s,m);
        MergeSort(r,r1,m+1,t);
        Merge(r,r1,s,m,t);
    }
}

6.计数排序
优点:计数排序(Count Sort)是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。
算法分析:计数排序是一种以空间换时间的排序算法,并且只适用于带排序中所有的数较集中是,比如一组序列中的数据为0 1 2 3 4 9999;就得开辟10000个辅助空间。
时间复杂度:
计数排序的时间复杂度理论为O(n+k),其中k为序列中数的范围。
不过当O(k)>O(n*log(n))的时候其效率反而不如基于比较的排序(比如归并排序)
原理:计数排序的思想类似于哈希表中的直接定址法,在给定的一组序列中,先找出该序列中的最大值和最小值,从而确定需要开辟多大的辅助空间,每一个数在对应的辅助空间中都有唯一的下标。

找出序列中最大值和最小值,开辟Max-Min+1的辅助空间
最小的数对应下标为0的位置,遇到一个数就给对应下标处的值+1,。
遍历一遍辅助空间,就可以得到有序的一组序列
在这里插入图片描述

void CountSort(int* array,int size)
{
    assert(array);
    int max = array[0];//序列中的最大值
    int min = array[0];//序列中的最小值
    for(int i = 0;i < size;++i)
    {
        if(array[i] >= max)
        {
            max = array[i];
        }
        else
        {
            min = array[i];
        }
    }
    int range = max - min + 1;//需要开辟的空间大小
    int* count = new int[range];
    memset(count,0,sizeof(int)*range);//辅助空间初始化为0,0代表没有那个数
    for(int i = 0;i < size;++i)
    {
        count[array[i] - min]++;//array[i]-min是将该数对应到辅助空间的下标
    }
    int index = 0;
    for(int i = 0;i < range;++i)//遍历辅助空间
    {
        while(count[i]--)//下标处的数值是几,说明该数出现了几次
        {
            array[index++] = i + min;//将下标处的数对应回原数组
        }
    }
    delete[] count;
}

7.桶排序
原理:桶排序的原理和技术排序的原理一样

8.基数排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值