【基础算法练习】快速排序模板

文章目录

  • 快排模板题
  • 我使用的快排模板
  • C++ 版本的快排
  • Golang 版本的快排
  • 为什么学习快排

快排模板题

第一道题,所有排序都适合在这里练习:912. 排序数组
第二道题,适合快排和堆排:215. 数组中的第K个最大元素

我使用的快排模板

我使用的是双指针版本的快排,双指针版本的快排的核心思想是:每一轮快排选择一个数作为 key,cur 遍历当前划分的区间,使得 key 左边的数小于 key,右边的数大于 key,这样就是升序,反之亦然

快排有很多种写法,我选择的是对于我来说最好理解的那个

温馨提示:LeetCode 那两道题目的数据都加强了,由于快排存在局限性,如果排序的是一个顺序的数组,我们可以用三数取中或者是随机选数来优化性能

但是,如果排序的是一个每一个数都完全相同的数组,那快排就完蛋了,而 LeetCode 那两道题都添加了数组元素全是 1 的样例,所以快排现在无论如何都没法过了

所以这两道题目,用快排的方法过显示的样例就行了

C++ 版本的快排

void quicksort(int l, int r, vector<int>& nums) {
    if (l >= r) {
        return;
    }
    swap(nums[(l+r)/2], nums[l]);
    int key = l, pre = l, cur = l+1;
    while(cur <= r) {
        if (nums[cur] < nums[key]) {
            pre++;
            swap(nums[pre], nums[cur]);
        }
        cur++;
    }
    swap(nums[pre], nums[key]);
    key = pre;
    quicksort(l, key-1, nums);
    quicksort(key+1, r, nums);
}

Golang 版本的快排

func quickSort(l, r int, nums []int) {
    if l >= r {
        return 
    }
    swap(&nums[(l+r)/2], &nums[l]);
    key, pre, cur := l, l, l+1
    for cur <= r {
        if nums[cur] < nums[key] {
            pre++
            swap(&nums[pre], &nums[cur])
        }
        cur++
    }
    swap(&nums[pre], &nums[key])
    key = pre
    quickSort(l, key-1, nums)
    quickSort(key+1, r, nums)
}

func swap(a, b *int) {
    *a, *b = *b, *a
}

Golang 版本比较惨,需要我手动实现 swap

为什么学习快排

主要有两个目的:

  1. 学习快排中蕴含的分治思想,练习基础算法,开阔思路
  2. 应对面试中可能出现的手撕快排的情况

你可能感兴趣的:(基础算法练习,算法)