排序算法 C++

一、 快速排序

思想:自上而下的分治法。对于区间 [ l , r ] [l,r] [l,r],一般选择 n u m s [ l ] nums[l] nums[l]作为标兵pivot,经过一轮排序,比pivot大的都在pivot右边,比pivot小的都在pivot左边。接下来分别对 [ l . p i v o t P o s − 1 ] [l.pivotPos-1] [l.pivotPos1], [ p i v o t P o s + 1 ] [pivotPos+1] [pivotPos+1]进行快排。

实际上,pivot相当于对标兵元素进行了暂存,因此标兵元素对应位置相当于为空,可以被其他元素直接覆盖。

例: n u m s = [ 51 , 46 , 18 , 43 , 32 , 112 , 41 , 84 , 53 , 2 , 15 ] nums=[51,46,18,43,32,112,41,84,53,2,15] nums=[51,46,18,43,32,112,41,84,53,2,15]

class SortMethods{
 public:  
 	// 双函数递归版本
    void quickSort(vector<int> &nums,int l,int r){
        if(r-l<=0)return ;
        int pivotPos=quickSort_findPivotPos(nums,l,r);
        quickSort(nums,l,pivotPos-1);
        quickSort(nums,pivotPos+1,r);
        
    }
    int quickSort_findPivotPos(vector<int> &nums,int l,int r){
        int pivot=nums[l];
        while(l<r){
            while(l<r && pivot<=nums[r])--r;
            nums[l]=nums[r];
            while(l<r&& pivot>=nums[l])++l;
            nums[r]=nums[l];
            
        }
        nums[l]=pivot;
        return l;
    }
    //单函数递归版本
    void quickSort2(vector<int> &nums,int l,int r){
        if(l>=r)return ;
        int i=l,j=r;
        int pivot=nums[i];
        while(i<j){
            while(i<j&&pivot<=nums[j])--j;
            nums[i]=nums[j];
            while(i<j&&pivot>=nums[i])++i;
            nums[j]=nums[i];
        }
        nums[i]=pivot;
        
        quickSort2(nums,l,i-1);
        quickSort2(nums,i+1,r);

    }
     //迭代版 借助栈对[l.r]进行存储,模拟函数调用
    //迭代版
    void quickSort3(vector<int> &nums,int l,int r){
        if(l>=r)return ;
        stack<pair<int,int>> stk;
        stk.push(pair<int,int>(l,r));
        while(!stk.empty()){
            auto pa=stk.top();
            stk.pop();
            //int l=pa.first,r=pa.second;
            //int i=l,j=r;
			int l,r,i,j;
            tie(l,r)=pa;
            tie(i,j)=pa;

            int pivot=nums[i];
            while(i<j){
                while(i<j&&pivot<=nums[j])--j;
                nums[i]=nums[j];
                while(i<j&&pivot>=nums[i])++i;
                nums[j]=nums[i];
             }
            nums[i]=pivot;
            //仅存储可行区间,与递归版的if(l>=r)return ;功能对应
            if(l<i-1)stk.push(make_pair(l,i-1));
            if(i+1<r)stk.push(make_pair(i+1,r));
        }
    }
};

// int main() {
//     vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
//     cout<<"排序前:";
//     for(auto val:nums)cout<<val<<",";
//     cout<<endl;
//     SortMethods s;
//     s.quickSort(nums,0,nums.size()-1);
//     cout<<"排序后:";
//     for(auto val:nums)cout<<val<<",";
//     cout<<endl;
// }

二、归并排序

思想:自底而上的分治思想。

class SortMethods{
 public:  
    //归并排序 递归
    void mergeSort(vector<int> &nums,int l,int r){
        if(l>=r) return;    
        int mid=l+(r-l)/2;
        mergeSort(nums,l,mid);//递归的“递”,分治
        mergeSort(nums,mid+1,r);//递归的“递”,分治
     
        vector<int> tmp(nums.begin()+l,nums.begin()+r+1);

        int i=0,j=mid+1-l;//注意:i,j用于索引tmp,[0,r-l],k用于索引nums,[l,r]
        int len=r-l;
        int k=l;
        while(i<=mid-l && j<=len){
            if(tmp[i]<=tmp[j]){
                nums[k++]=tmp[i++];
            }else{
                nums[k++]=tmp[j++];
            }
        }
        while(i<=mid)nums[k++]=tmp[i++];
        while(j<=len)nums[k++]=tmp[j++];
   }
};
// int main() {
//     vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
//     cout<<"排序前:";
//     for(auto val:nums)cout<<val<<",";
//     cout<<endl;
//     SortMethods s;
//     s.mergeSort(nums,0,nums.size()-1);
//     cout<<"排序后:";
//     for(auto val:nums)cout<<val<<",";
//     cout<<endl;
// }

三、堆排序

  1. 使用C++ make_heap(v.begin(),v.end(),less< int >() );将序列容器中的元素建立为大顶堆;
  2. 每次使用pop_heap(v.begin(),v.end()-i,less< int >() ),将堆顶元素调整到当前堆的末尾;
    (C++ 堆的原理 可参考: https://mp.weixin.qq.com/s/U9sJqvxvCGuwVZrdA-0PKQ )
class SortMethods{
 public:  
    void heapSort(vector<int> & nums){
        if(nums.size()<=0)return ; 
        make_heap(nums.begin(),nums.end(),less<int>());
        int i=0;
        while(i<nums.size()){
            pop_heap(nums.begin(),nums.end()-i,less<int>());
            ++i;
        }
    }
};
// int main() {
//     vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
//     cout<<"排序前:";
//     for(auto val:nums)cout<<val<<",";
//     cout<<endl;
//     SortMethods s;
//     // s.quickSort(nums,0,nums.size()-1);
//     // s.mergeSort(nums,0,nums.size()-1);
//     s.heapSort(nums);
//     cout<<"排序后:";
//     for(auto val:nums)cout<<val<<",";
//     cout<<endl;
// }

四、冒泡排序(优化)

思想 每轮中每步调整两个相邻元素的顺序,每轮保证最大元素排在末尾

class SortMethods{
 public:  
    //bubble sort with optimization 
    void bubbleSort(vector<int> &nums){
        if(nums.size()<=1)return ;
        for(int i=0;i<nums.size()-1;++i){
            bool isSorted=true;//每轮设置flag,如果剩余元素均为有序,跳出i的循环
            for(int j=i+1;j<nums.size();++j){
                if(nums[i]>nums[j]){
                    swap(nums[i],nums[j]);
                    isSorted=false;
                }
            
            }
           if(isSorted)break;
        }
    }
};
int main() {
    vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
    cout<<"排序前:";
    for(auto val:nums)cout<<val<<",";
    cout<<endl;
    SortMethods s;
    // s.quickSort(nums,0,nums.size()-1);
    // s.mergeSort(nums,0,nums.size()-1);
    // s.heapSort(nums);
    s.bubbleSort(nums);
    cout<<"排序后:";
    for(auto val:nums)cout<<val<<",";
    cout<<endl;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值