温习一下快排和归并排序,假装在面试手撕,再加一个使用标准库std::partition函数实现二分原位重排的快排

本文提供了一种快速排序和一种归并排序的具体实现方法,包括C++代码示例及Python版归并排序。快速排序采用原地重排方式减少额外空间需求,归并排序通过递归将数组拆分再合并实现排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每次写出来都不一样,说明我是人不是机器。

#include<iostream>
#include<vector>
void FastSort(std::vector<int> &arr,int is,int ie){
    if(is>=ie)return;
    int i(is),j(ie);
    int val(arr[i]);    //如果要用中间元素arr[(is+ie)/2]那直接和arr[is]交换一下swap(arr[(is+ie)/2],arr[is])
    while(i<j){
        while(i<j && arr[j]>=val)j--;   //跳过等于的,保持稳定
        if(i<j){
            arr[i]=arr[j];
            i++;
        }
        while(i<j && arr[i]<=val)i++;   //跳过等于的,保持稳定
        if(i<j){
            arr[j]=arr[i];
            j--;
        }
    }
    arr[i]=val;
    FastSort(arr,is,i-1);   //二分
    FastSort(arr,i+1,ie);
    return;
}
void GuibinSort(std::vector<int> &arr,int is,int ie){    //归并排序
    if(is>=ie)return;
    if(is==ie-1){
        if(arr[is]>arr[ie]) std::swap(arr[is],arr[ie]);
        return;
    }
    int im((is+ie)/2);
    GuibinSort(arr,is,im);
    GuibinSort(arr,im+1,ie);
    //组装
    std::vector<int> arrt(ie-is+1,0);
    int i(is),j(im+1),k(0);
    while(i<=im && j<=ie){
        if(arr[i]<=arr[j])arrt[k++]=arr[i++]; //如果相等则先压左边,保持稳定
        else arrt[k++]=arr[j++];
    }
    if(i>im){   //左边用尽
        while(j<=ie)arrt[k++]=arr[j++];
    }else if(j>ie){
        while(i<=im)arrt[k++]=arr[i++];
    }
    for(int m(0);m<ie-is+1;m++) arr[is+m]=arrt[m];
    return;
}
int main(int argc,char *argv[]){
    std::vector<int> arr{3,1,4,1,5,9,2,6};
    FastSort(arr,0,arr.size()-1);
    for(int i(0);i<arr.size();i++)std::cout<<arr[i]<<" ";
    std::cout<<"\n";

    std::vector<int> arr2{3,1,4,1,5,9,2,6};
    GuibinSort(arr2,0,arr2.size()-1);
    for(int i(0);i<arr.size();i++)std::cout<<arr2[i]<<" ";
    std::cout<<"\n";
}

编译运行:

VMCatalina:Exception haypin$ clang++ -g fastsort.cpp -std=c++11 -o main
VMCatalina:Exception haypin$ ./main
1 1 2 3 4 5 6 9 
1 1 2 3 4 5 6 9 
VMCatalina:Exception haypin$

转自《C Concurrent In Action 2nd》4.4.1给出的,使用C++标准库std::partition()函数以序列首元素为基准实现二分原位重排的快排:

#include<iostream>
#include<list>
template<typename T>
std::list<T> FastSort(std::list<T> input){
    if(input.empty()) return input;
    std::list<T> result;
    //1、首先将链表首元素移动到结果链表result
    result.splice(result.begin(),input,input.begin());  
    T const &pivot=*result.begin();
    //2、将链表剩下的元素按"小于首元素的放前面,不小于首元素的放后面"原则重排(原位重排)
    //,并返回后面部分最前面元素的迭代器
    auto divide_point=
    std::stable_partition(input.begin(),input.end(),[&](T const& t){return t<pivot;});
    
    std::list<T> lower_part;
    //3、移动已经重排过的链表的小于分界值的部分
    lower_part.splice(lower_part.end(),input,input.begin(),divide_point);
    //4、二分递归排序
    auto new_lower(FastSort(std::move(lower_part))); //小于分界值的部分,实参移动到形参而不是拷贝
    auto new_higher(FastSort(std::move(input))); //剩下的,分界值之后大于的部分
    
    //5、组装二分重排部分
    result.splice(result.end(),new_higher); //分界点之后大于的部分
    result.splice(result.begin(),new_lower);
    return result;
}
int main(int argc,char *argv[]){
    std::list<int> arr{3,1,4,1,5,9,2,6};
    arr=FastSort(arr);
    std::for_each(arr.begin(),arr.end(),[](int &ele){std::cout<<" "<<ele;});
    std::cout<<"\n";
}

编译运行:

HaypinsMBP:MultiThread haypin$ clang++ -g slice.cpp -std=c++11 -o main
HaypinsMBP:MultiThread haypin$ ./main
 1 1 2 3 4 5 6 9
HaypinsMBP:MultiThread haypin$ 

210728补充一个python的归并排序:

#!/usr/bin/env python
#-*- coding: utf-8 -*-
def GuibinSort(data=[],istart=0,iend=0):
    if istart >=iend:
        return
    imid = int((istart+iend)/2)
    GuibinSort(data,istart,imid)
    GuibinSort(data,imid+1,iend)
    arr = []
    i = istart
    j = imid+1
    while i<=imid and j<=iend:
        if data[i]<=data[j]:    # stable
            arr.append(data[i])
            i+=1
        else:
            arr.append(data[j])
            j+=1
    if i>imid:
        while j<=iend:
            arr.append(data[j])
            j+=1
    else:
        while i<=imid:
            arr.append(data[i])
            i+=1
    i = istart
    while i<=iend:
        data[i]=arr[i-istart]
        i+=1
    return
if __name__ =='__main__':
    mylist = [3,1,4,1,5,9,2,6]
    GuibinSort(mylist,0,len(mylist)-1)
    print(mylist)

运行:

 haypin@MBP  ~/catkin_ws/src/creeper   main  python guibinSort.py
[1, 1, 2, 3, 4, 5, 6, 9]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值