分治法|快速排序

首先是伪代码

QuickSort(A[l...r])
//用QuickSort对子数组进行排序
//输入:叔祖A[0...n-1]中子数组A[l..r],由左右下标l和r定义
//输出:非降序排列的子数组A[l...r]
if l<r
    s<-Partition(A[l.r])//找到轴值,并且划分数组
    QuickSort(A[l...s-1])
    QuickSort(A[s+1...r])

LomutoPartition划分方法

LomutoPartition(A[l...r])
//采用LomutoPartition算法,用第一个元素作为中轴对子数组进行划分
//输入:数组A[0...n-1]的一个子数组A[l..r],它由左右二边的索引l和r定义
//输出:A[l..r]的划分和中轴的新位置

//第一步,先选取第一个元素为轴值
1.p<-A[l]

//第二步,s为首指针,给s赋初值
2.s<-l

//第三步,排序
3.for i<-l+1 to r do
        if A[i]<p
            s<-s+1;swap(A[s],A[i])

//第四步,把轴值放到它的位置
4.swap(A[l],A[s])
return s

 就是将比p小的数字放到p的前面

HoarePartition算法

HoarePartition(A[l...r])
//以第一个元素为中轴,对子数组进行划分
//输入:数组A[0...n-1]中的子集A[l...r],由左右下标l和r定义
//输出:A[l...r]的一个划分,分裂点作为函数的返回值

//第一步,选取第一个元素为轴值
1.p<-A[l]

//第二步,设置一个首指针,一个尾指针
2.i<- l;j<-r+1;

//第三步,i从l+l加一开始,j从r开始(这俩个repeat是并列的)
3.repeat(重复)
    repeat i<- i+1 until A[i]>=p
    repeat j<- j-1 until A[j]<=p
    swap(A[i],A[j])
//结束条件:i>=j
until i>=j

//第四步
//当i>=j撤销最后一次交换
4.swap(A[i],A[j])

//第五步,将轴值换到本来的位置
5.swap(A[l],A[j])
return j

 接下来是代码实现

大致思想一样,可能有些步骤与算法不太一样

//hoare算法

//HoarePartition排序
int HoarePartition(int *a,int l,int r){
    //选取第一个元素为轴值
    int key=l;
    //定义一个首指针一个尾指针
    int i=l,j=r;
    //开始排序
    while(i<j){
        while(i<j && a[i]<=a[key]){
            i++;
        }
        while(i<j && a[j]>=a[key]){
            j--;
        }
        swap(a[i],a[j]);
}
//把轴值放在它的位置
swap(a[i],a[key]);
//找到下一个轴值
key=i;
return key; 
}

//快排函数
 void Qsort(int *a,int begin,int end){
     if(begin>=end) return;
     int key=HoarePatition(a,begin,end);//每次都返回轴值
     //划分左区间
     Qsort(a,begin,key-1);
     Qsort(a,key+1,end);
}
//LomutoPartition算法
int LomutoPartition(int *a,int l,int r){
    int p=a[l];
    int s=l;
    for(int i=l+1;i<=r;i++){
        if(a[i]<p)
        {
            s=s+1;
            swap(&a[s],&a[i]);
        }
    }
    swap(&a[l],&a[s]);
    return s;
}

2024年10月6日更新

2024年10月13日发现还有一些问题,晚上再修改一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值