常用排序算法的实现C++

16 篇文章 0 订阅

1.快排

左闭右闭的二分写法

void quick_sort(vector<int> &nums, int l, int r) {
    if (l + 1 >= r) {
        return;
    }
    int first = l, last = r - 1, key = nums[first];
    while (first < last){
        //一轮
        while(first < last && nums[last] >= key) {//从后往前找比枢轴小的元素
            --last;
        }
        nums[first] = nums[last];//找到后填补到原来的枢轴位置

        while (first < last && nums[first] <= key) {//从前往后找比枢轴大的元素
            ++first;
        }
        nums[last] = nums[first];//填补last的位置
    }
    nums[first] = key;
    quick_sort(nums, l, first);
    quick_sort(nums, first + 1, r);
}

快排可改进为快速选择算法,用来在未排序的数组中寻找第K小/大的元素,思路:选择一个元素作为基准来对元素进行分区,将小于和大于基准的元素分在基准左边和右边的两个区域。不同的是,快速选择并不递归访问双边,而是只递归进入一边的元素中继续寻找。这降低了平均时间复杂度,从O(n log n)至O(n),不过最坏情况仍然是O(n2)。

class Solution {//找第K大元素
public:
    int quickSelect(vector<int>& nums,int l,int r){
        int i=l+1,j=r;//注意i初始为l+1
        while(true){
            while(i<r && nums[i]<=nums[l])//找大于枢轴的元素
                ++i;
            while(l<j && nums[j]>=nums[l])//找小于枢轴的元素
                --j;
            if(i>=j)//比枢轴大的元素在比枢轴小的元素的右侧,不用调换位置
                break;
            swap(nums[i],nums[j]);//比枢轴大的元素在比枢轴小的元素的左侧,调换位置
        }
        swap(nums[l],nums[j]);//交换j元素到枢轴位置
        return j;//返回枢轴位置
    }

    int findKthLargest(vector<int>& nums, int k) {//算法主体
        int l=0,r=nums.size()-1,target=nums.size()-k;
        while(l<r){//二分
            int mid=quickSelect(nums,l,r);//得到划分
            if(mid==target)
                return nums[mid];
            if(mid<target)
                l=mid+1;
            else
                r=mid-1;
        }
        return nums[l];
    }
};

2.归并排序

void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp) {
    if (l + 1 >= r) {
        return;
    }
    // divide
    int m = l + (r - l) / 2;
    merge_sort(nums, l, m, temp);
    merge_sort(nums, m, r, temp);
    // conquer
    int p = l, q = m, i = l;
    while (p < m || q < r) {
        if (q >= r || (p < m && nums[p] <= nums[q])) {
            temp[i++] = nums[p++];
        } 
        else {
        temp[i++] = nums[q++];
        }
    }
    for (i = l; i < r; ++i) {
        nums[i] = temp[i];
    }
}

3.插入排序

void insertion_sort(vector<int> &nums, int n) {
    for (int i = 0; i < n; ++i) {
        for (int j = i; j > 0 && nums[j] < nums[j-1]; --j) {
            swap(nums[j], nums[j-1]);
        }
    }
}

4.冒泡排序

void bubble_sort(vector<int> &nums, int n) {
    bool swapped;
    for (int i = 1; i < n; ++i) {
        swapped = false;
        for (int j = 1; j < n - i + 1; ++j) {
            if (nums[j] < nums[j-1]) {
                swap(nums[j], nums[j-1]);
                swapped = true;
            }
        }
        if (!swapped) {
            break;
        }
    }
}

5.选择排序

void selection_sort(vector<int> &nums, int n) {
    int mid;
    for (int i = 0; i < n - 1; ++i) {
        mid = i;
        for (int j = i + 1; j < n; ++j) {
            if (nums[j] < nums[mid]) {
                mid = j;
            }
        }
    swap(nums[mid], nums[i]);
    }
}

调用格式

void sort() {
    vector<int> nums = {1,3,5,7,2,6,4,8,9,2,8,7,6,0,3,5,9,4,1,0};
    vector<int> temp(nums.size());
    sort(nums.begin(), nums.end());
    quick_sort(nums, 0, nums.size());
    merge_sort(nums, 0, nums.size(), temp);
    insertion_sort(nums, nums.size());
    bubble_sort(nums, nums.size());
    selection_sort(nums, nums.size());
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值