快速排序算法 和 归并排序算法

本文详细介绍了两种经典的排序算法——归并排序和快速排序。归并排序通过递归将数组分成两部分,再进行有序合并,保证了稳定性,时间复杂度为O(nlogn),空间复杂度为O(n)。而快速排序则采用基准值划分数组,通过双指针调整,平均时间复杂度同样为O(nlogn),但空间复杂度更低,为O(logn)。这两种算法在实际应用中各有优势。
摘要由CSDN通过智能技术生成

ps:排序算法是否稳定的依据:相同数值的数字在排序后的相对位置是否跟原来一样

归并排序,先利用递归,以中点分界,排成两段有序序列。
然后用双指针算法,分别对这两段序列从头到尾遍历,并且每一个做对比,把小的放入新的一个数组里面。合二为一,最后把临时数组的数据拷贝回原来的数组,完成归并排序。

时间复杂度 O(nlogn),空间复杂度(n);

#include <bits/stdc++.h>
using namespace std;

vector<int> temp(1e5 + 10);

void merge_sort(vector<int> &q, int left, int right) {
    if (left >= right) return;
    int mid = left + (right - left) / 2;
    merge_sort(q, left, mid);
    merge_sort(q, mid + 1, right);
    int i = left, j = mid + 1;
    int k = 0;
    while (i <= mid && j <= right) {
        if (q[i] > q[j]) temp[k++] = q[j++];
        else temp[k++] = q[i++];
    }
    
    while (i <= mid) temp[k++] = q[i++];
    while (j <= right) temp[k++] = q[j++];
    for (i = left, j = 0; i <= right; i++, j++) q[i] = temp[j];
}

int main() {
    int n;
    cin >> n;
    vector<int> q(n);
    for (auto &x : q) cin >> x;
    merge_sort(q, 0, n - 1);
    for (auto x : q) cout << x << " ";
    cout << endl;
    return 0;
}

快速排序
对于一段乱序数组,可以随机选取一个值,一般选中间点作为基准值。
然后分别用双指针算法在头跟尾各自往中间扫描,遇到不合适的条件时,停下来,交换。目的是为了让基准值左边的数都小于基准值,让基准值右边的数都大于基准值。然后再递归处理。完成快排。

时间复杂度O(nlogn), 空间复杂度(logn);

#include <bits/stdc++.h>
using namespace std;

void quick_sort(vector<int> &q, int left, int right) {
    if (left >= right) return;
    int i = left - 1, j = right + 1;
    int mid = left + (right - left) / 2;
    int midVal = q[mid];
    //中间点可以任意取,但是下面递归边界写的是j和j + 1,这里就不能取q[r]
    //反之如果下面递归取的是i-1和i,这里就不能取q[l],否则会发生无限递归,如数组1,2,(会有一个递归区间无限重复循环)
    while (i < j) {
        while (q[++i] < midVal);
        while (q[--j] > midVal);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, left, j);
    quick_sort(q, j + 1, right);
}


int main() {
    int n;
    cin >> n;
    vector<int> q(n);
    for (auto &x : q) cin >> x;
    quick_sort(q, 0, n - 1);
    for (auto x : q) cout << x << " ";
    cout << endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值