排序算法~快速排序【Rust】

排序算法~快速排序

快速排序在平均情况下排序 n n n 个项目需要 O ( n l o g n ) O(nlog n) O(nlogn) 次比较,在最坏情况下则需要 O ( n 2 ) O(n^2) O(n2) 次比较

快速排序通常比其它时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn) 的排序算法要快

分治法Divide and conquer策略是把一个串行list分为两个子串行sub-list

快速排序是分治法的一种典型应用

快速排序的步骤简而言之就是选择一个基准值,然后将数列的其它值放到基准值的左右两边

  1. 从数列中挑选一个元素,称为基准(pivot)
  2. 重新排序数列,所有比基准值小的放在基准值左边,所有比基准元素大的放到右边(相同的数字可以放在容易一边),这一轮操作后,这个操作成为分区(partition)操作
  3. 然后递归的把每一个分区操作得到的子数列进行分区操作

快速排序的基准值的选择没有做特别说明

快速排序的不稳定是指排序后可能会使两个相同的值的位置交换

快速排序的实现

pub fn quick_sort(vector: &mut Vec<i32>) {
    quick_sort_inside(vector, 0, vector.len());
}

fn quick_sort_inside(vector: &mut Vec<i32>, left: usize, right: usize) {
    // 当需要排序的分区长度小于 2 时就可以结束递归了
    if right - left < 2 { return; }
    // 对数列的 [left, right) 部分进行排序,并返回第一个大于或者等于基准数所在的位置
    let p = partition(vector, left, right);
    // 对数列的 [left, p) 部分进行排序
    quick_sort_inside(vector, left, p);
    // 对数列的 [p, right) 部分进行排序
    quick_sort_inside(vector, p, right);
}

fn partition(vector: &mut Vec<i32>, p: usize, l: usize) -> usize {
    // 选取基准值(这里可以进行优化,使用随机数或者三数取中等)
    let pivot = vector[(l + p) / 2];
    // 对数列进行交互时需要使用到的中间变量
    let mut temp: i32;
    // 比基准值小的数的当前指针
    let mut prev = p;
    // 比基准值大的数的当前指针
    let mut last = l - 1;

    loop {
        // 将左指针移动到比基准值大的数
        while vector[prev] < pivot && prev < last { prev += 1; }
        // 将右指针移动到比基准值小的数
        while vector[last] > pivot && prev < last { last -= 1; }
        // 如果移动后,左指针大于等于右指针了,则表示当前分区已经排序完成了
        if prev >= last { break }
        // 交换当前的大数与小数
        temp = vector[last];
        vector[last] = vector[prev];
        vector[prev] = temp;
        // 使当前的前指针向后移动一位
        prev += 1;
    }
    return prev
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值