1.20(排序函数的快写)

一、快速排序(Quick'Sort)

01        快速排序的思想
        快速排序是一种基于分治法的排序方法,原理是将一个数组分分成两个子数组,其中一个子数
组的所有元素都小于另一个子数组的元素,然后递归地对这两个子数组进行排序。
        快速排序的思想是通过不断地将数组分成两个子数组,递归他对子数组进行排序,最终得到
一个有序的数组。这个过程通过选择合适的基准和分区操作来实现。
        快速排序拥有更好的时间复杂度O(nlogn),且不需要额外空间。
02快速排序的实现

void QuickSort(int a[],int l,int r){
    if(l<r){
        int mid=partition(a,l,r);        //partition函数定位,进行分组
        QuickSort(a,l,mid-1);            //分组后继续分治处理
        QuickSort(a,mid+1,r);
    }
}
int partition(int a[],int l,int r){
    int pivot=a[r];                      //寻找a[r]在数组中合适的位置
    int i=l,j=r;
    while(i<j){
        while(i<j&&a[i]<=pivot)i++;      //将比a[r]大的数和小的数放在一边
        while(i<j&&a[j]>=pivot)j--;
        if(i<j)swap(a[i],a[j]);
        else swap(a[i],a[r]);            //i=j;此时i,j指向同一位置,即a[r]应处位置;
    }
return i;
}

二、插入排序(insertSort)

01插入排序的思想
        插入排序是一种简单直观的排序算法,其基本思想是将待排序的元素逐个插入到已排序序列
的合适位置中,使得已排序序列逐渐扩大,从而逐步构建有月序列,最终得到完全有序的序
列。
        它类似于我们打扑克牌时的排序方式,将一张张牌插入到已经有序的手牌中。
        时间复杂度为O(n^2)。

02插入排序的实现

for(int i=2;i<=n;i++){
       //此时[1,i-1]为已排序的有序数列
    int val=a[i],j;            
       //从a[i]开始继续插入,j用于存放a[i]正确的位置;
    for(j=i;j>0&&a[j-1]>val;j--)
        a[j]=a[j-1];           
        //将大于a[i]的向后挪一位
    a[j]=val;                 
        //将a[i]插入
    
}

三、选择排序(select Sort)
01选择排序的思想
        选择排序的思想和冒泡排序类似,是每次找出最大的然后直接接放到右边对应位置,然后将最
右边这个确定下来(而不是一个一个地交换过去)。
        再来确定第二大的,再确定第三大的....
        对于数组a[,具体的来说,每次确定操作(假设当前要确定的是i位置)就是从左往右扫描,
计算出最大元素的下标max_id,最后执行一次swap(a[max_id],a[i])将路两项交换即可
        第一次确定操作是将a[1]~a[n]中最大的放到a[n];
        第二次确定操作是将a[1]~a[n-1]中最大的放到a[n-1]。
        类推(类似地,如果你想先把最小的放到左边也是可以的),时间复杂度为0(n^2)

02选择排序的实现

//对a[n]数组进行选择排序;
for(int i=n;i>0;i--){
    int max_id=1;
    for(int j=1;j<=i;j++){
        if(a[j]>a[max_id])max_id=j;    //找出最大数的位置
    }
    swap(a[max_id],a[i]);
}

四、归并排序(mergeSort)

01归并排序的思想
        归并排序和快速排序类似,也是一种基于分治法的排序方法。
        原理是将一个数组分成两个子数组,将子数组向下递归的排用序后(当数组中仅有一个元素值
无需再排序了,直接返回),得到两个有序数组,然后进行0(n)的名合并,最终合并成有序的原数组。

        快速排序拥有较好的时间复杂度O(nlogn),但需要额外的空间用于合并数组。

02归并排序的实现

void MergeSort(int a[],int l,int r){
    if(l==r)return;        //当区间长度为1时,排序结束;

    int mid=(l+r)/2;        //将数组分治
                     
    MergeSort(a,l,mid);
    MergeSort(a,mid+1,r);
                //得到了两端有序的数组a[l]-a[mid]和a[mid+1]-a[r]
    int pl=l,pr=mid+1,pb=1;
                //pl为左段的下标,pr为右段的下标,pb为数组b[]的下标,b[]为辅助的数组;
    while(pl<=mid||pr<=r){
        if(pl>mid)            //左段已经放完,直接将右段放入
            b[pb++]=a[pr++];        
        else if(pr>r)         //右段已经放完,直接将左段放入
            b[pb++]=a[pl++]; 
        else{
            if(a[pl]>a[pr])b[pb++]=a[pr++];    //取小放入
            else b[pb++]=a[pl++];
        }
    }
    for(int i=1;i<=n;i++)a[i]=b[i];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值