关于基础排序

目录

冒泡排序:

选择排序:

插入排序:

归并排序:

快速排序:

堆排序:

参考文献:


冒泡排序:

比较相邻元素:首先比较数组中的相邻两个元素。如果第一个比第二个大,则交换这两个元素的位置。这样,较大的数就会逐渐“浮”到数组的末尾。

多轮比较:接下来,对数组进行下一轮比较,从开始到结尾,但排除已经排序好的最大数。这一轮中,较大的数会被继续交换到数组的末尾。

重复过程:持续进行上述步骤,直到整个数组有序排列。在每一轮中,都会有一个元素被“冒泡”到正确的位置。

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int min_x;int max_x;
        int n=nums.size();
        for(int i=0;i<nums.size();i++){//表示后面已经处理好的元素
            for(int j=0;j<n-i-1;j++){
                min_x=min(nums[j],nums[j+1]);max_x=max(nums[j],nums[j+1]);
                nums[j]=min_x;nums[j+1]=max_x;
            }
        }
        return nums;
    }
};

选择排序:

在待排序的序列中依次选出最小(或最大)的元素,存放到序列的起始位置,然后再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

class Solution {//选择排序
public:
    vector<int> sortArray(vector<int>& nums) {
        int x_min;//标记最小值
        int i_min;//标记最小值的位置
        for(int i=0;i<nums.size();i++){
            x_min=nums[i];i_min=i;//重置最小值与对应位置
            for(int j=i+1;j<nums.size();j++){
                if(nums[j]<x_min){x_min=nums[j];i_min=j;}
            }
            if(i_min!=i){nums[i_min]=nums[i];nums[i]=x_min;}
        }
        return nums;
    }
};

插入排序:

将元素插入到已经排序好的序列中来进行排序。

(1)从第2个元素开始,选取第2个元素(i),认为第1个元素为一个只有一个元素的有序列表。
(2)将选取的元素与之前的元素依次比较,如果选取的元素小于于列表中的元素,交换他们的位置。
(3)选取下一个元素(i+1),重复步骤(2),直至列表中的每个元素都进行了步骤(2)的操作。

class Solution {//插入排序
public:
    vector<int> sortArray(vector<int>& nums) {
        for(int i=0;i<nums.size();i++){//需要插入到前面序列的新元素
            int x=nums[i];
            int j=i-1;
            for(;j>=0;j--){
                if( x <nums[j] ){
                    nums[j+1]=nums[j];
                }else{
                    break;
                }
            }
            nums[j+1]=x;//注意这一步的位置
        }
        return nums;
    }
};

归并排序:

归并排序流程:

  1. 分解:将数组分为两部分,如果数组长度为n,则分为n/2和n/2的两部分。
  2. 归并:对每一部分进行归并排序,即从小到大排序。
  3. 合并:将排序好的两部分合并为一个有序的整体。
class Solution {//归并排序
public:
    void merge(vector<int>& nums,int left,int mid,int right){//合并函数
        vector<int>vec_left(nums.begin()+left,nums.begin()+mid+1);
        vector<int>vec_right(nums.begin()+mid+1,nums.begin()+right+1);
        int i=left;int l=0;int r=0;
        while(i<=right && l<vec_left.size() && r<vec_right.size()){
            if(vec_left[l]<vec_right[r]){nums[i]=vec_left[l];l++;i++;}
            else{nums[i]=vec_right[r];r++;i++;}
        }
        if(l<vec_left.size()){
            for(;i<=right;i++){nums[i]=vec_left[l];l++;}
        }
        if(r<vec_right.size()){
            for(;i<=right;i++){nums[i]=vec_right[r];r++;}
        }
    }
    void mergeSort(vector<int>& nums,int left,int right){//进行分治与合并的主函数
        if(left<right){
            int mid=left+(right-left)/2;
            mergeSort(nums,left,mid);
            mergeSort(nums,mid+1,right);
            merge(nums,left,mid,right);
        }
    }
    vector<int> sortArray(vector<int>& nums) {
        mergeSort(nums,0,nums.size()-1);
        return nums;
    }
};

快速排序:

快速排序是一种分而治之的算法,它选择一个基准值(pivot)并围绕它对数组进行分区,将小于基准值的元素移到其左侧,将大于基准值的元素移到其右侧。然后递归地对基准值左右两边的子数组进行相同的操作,直到整个数组排序完成。

class Solution {
public:
    int patition(vector<int>& arr,int low,int high){
        int pivot=arr[high];//使用数组最右侧数据作为基准元素
        int i=low-1;//初步定义小于加准元素的边界线,并不断扩大更新该边界线
        for(int j=low;j<=high-1;j++){
            if(arr[j]<=pivot){//当前元素小于基准元素
                i++;//扩大小于基准元素的边界线
                swap(arr[i],arr[j]);//交换
            }
        }
        swap(arr[i+1],arr[high]);//最后交换基准元素,使其摆在合适的位置上
        return i+1;//返回划分好的“分水岭”的位置
    }
    void quickSort(vector<int>& arr,int low,int high){
        if(low<high){
            int pi=patition(arr,low,high);//将数组分为小于x,等于x,大于x三部分
            quickSort(arr,low,pi-1);//对左部分进行进一步的快排
            quickSort(arr,pi+1,high);//对右部分进行进一步的快排
        }
    }
    vector<int> sortArray(vector<int>& nums) {
        quickSort(nums,0,nums.size()-1);
        return nums;
    }
};

堆排序:

参考文献:

常见的几种排序算法(c++)_c++排序算法-CSDN博客

C++常见十大排序_c++排序-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值