十大排序算法——快排算法(quicksort)
本文最后更新于39 天前,其中的信息可能已经过时,如有错误请留言

快排的算法逻辑理解起来不复杂,但要实现起来,真还不是很容易。尤其是怎么处理交换这一块,让所有比选中数字小的值都到左边,比选中数字大的数都到右边,然后把选中的数字放在这两者之间,确实不容易,我将一种我认为性能比较好的方法写在了下面。

#include <vector>
#include <algorithm>
#include <iostream>
#include <random>
using namespace std;

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        random_device rd;
        mt19937 g(rd());
        shuffle(nums.begin(), nums.end(), g);
        quicksort(nums, 0, nums.size() - 1);
        return nums;
    }
private:
    void sort(vector<int>& nums, int start, int end) {
        if (start >= end) { /* 保证了nums的长度大于等于2 */
            return;
        }
        int p = quicksort(nums, start, end);
        sort(nums, start, p - 1);
        sort(nums, p + 1, end);
    }

    int quicksort(vector<int>& nums, int start, int end) {

        int i = start + 1;
        int j = end;
        int num = nums[start];
        while (true) {
            while (i < end && nums[i] <= num) { /* 从start + 1开始从左向右寻找比num大的数组下标 */
                i++; /* 当该循环结束时,nums[i] > num 或者 i == end */
            }
            while (j > start && nums[j] > num) { /* 从end开始从右向左寻找比num小的数组下标 */
                j--; /* 当该循环结束时,因为nums[start] == num,所以无论j是否等于start,nums[j] <= num */
            }
            /* 当所有数值都刚好排序好的临界时刻,i + 1 == j,此时nums[i] <= num,nums[j] > num */
            /* 进入下一次循环之后,i++, j--,此时i == j + 1,此时应该退出循环,因为start + 1至end部分已经排序完成 */
            /* 还有一种可能性,那就是i == j,这种情况下,nums[i] <= num,如果nums[i] > num,上面提到,nums[j] <= num必然成立,所以i和j无论如何不可能相等,所以nums[i] <= num */
            /* nums[i] <= num i++的循环结束必然是由于i == end,所以此时i == end,而此时i == j,所以此时i == j == end,说明此时从start + 1到end的所有数值均小于num */
            if (i >= j) { /* 综上所述,在nums[start]是从start到end中的最大值时,此时循环会因为i == j结束,其余情况,均因为i > j结束 */
                break;
            }
            // for_each(nums.begin(), nums.end(), [](int num){ cout << num << " ";});
            // cout << endl;
            /* 情况1:nums[start], nums[start + 1]...nums[j - 1], nums[j], nums[i]...nums[end] */
            /* 情况2:nums[start], nums[start + 1]...nums[j - 1], nums[j] */
            swap(nums[i], nums[j]); /* nums[i]和nums[j]交换之后,从start + 1到i的所有数值都小于等于num,从j到end的所有数值都大于num */
        }
        swap(nums[start], nums[j]);
        return j;
    }
};

int main()
{
    Solution s1;
    vector<int> nums = {5, 2, 3, 1};
    s1.sortArray(nums);
    for_each(nums.begin(), nums.end(), [](int num){ cout << num << " ";});
    cout << endl;
}

感谢阅读!如有疑问请留言
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇