快速排序写法

双指针写法 递归

template <typename Comparable>
int partition(vector<Comparable>& v, int left, int right) {
    if (left >= right) return left;
    int i = left, j = right;
    Comparable pivot = v[left];
    while (i < j) {
        while (i < j && !(v[j] < pivot)) j--;//注意这里的判断条件,和下面的区别
        v[i] = v[j];
        while (i < j && v[i] < pivot) i++;
        v[j] = v[i];
    }
    v[i] = pivot;
    return i;
}
template <typename Comparable>
void quicksort1(vector<Comparable>& v, int left, int right) {
    if (left >= right) return;
    int mid = partition(v, left, right);
    quicksort1(v, left, mid - 1);
    quicksort1(v, mid + 1, right);
}

借用栈 非递归

template <typename Comparable>
void quicksort2(vector<Comparable>& v, int left, int right) {
    if (left >= right) return;
    stack<int> s;
    s.push(left);
    s.push(right);
    //用栈保存每一个待排序子串的首尾元素下标,下一次while循环时取出这个范围,对这段子序列进行partition操作
    while (!s.empty()) {
        int right = s.top();
        s.pop();
        int left = s.top();
        s.pop();
        if (left < right) {
            int boundary = partition(v, left, right);
            // 左区间
            s.push(left);
            s.push(boundary - 1);
            // 右区间
            s.push(boundary + 1);
            s.push(right);
        }
    }
}

性能比较

实际上这里,递归算法快于非递归算法。

借用栈或队列将递归算法改为非递归,不一定会带来好处。

快速排序和冒泡排序

共同点:

  1. 都要经历n趟排序。
  2. 每趟排序要经历O(n)次比较。
  3. 都是后半部分元素比前半部大。

不同点:

  1. 冒泡排序的交换操作发生相邻的元素之间,即一趟排序要经过多次交换操作。
  2. 快速排序的交换操作发生在间隔比较远的两个元素之间,一趟排序要经过交换操作次数会少一些。
  3. 冒泡是稳定的,快排是不稳定的。
posted @ 2022-05-20 10:12  天下太平  阅读(53)  评论(0编辑  收藏  举报