快速排序的两种C++实现,复杂度分析及优化

快速排序可能是面试中最常被考察的算法了,求职者一定要非常熟练地掌握掌握这一算法。
下面介绍该算法的两种C++实现方法:

  • 方法一:
void quickSort(vector<int> &nums, int b, int e) {
    if (b < e) {
        int pivot = nums[b];   //选取第一个元素为pivot
        int i = b, j = e;
        while (i < j) {
            while (i < j && nums[j] > pivot) {
                j--;
            }
            if (i < j) {
                nums[i++] = nums[j];
            }
            while (i < j && nums[i] < pivot) {
                i++;
            }
            if (i < j) {
                nums[j--] = nums[i];
            }
        }
        nums[i] = pivot;
        quickSort(nums, b, i - 1);
        quickSort(nums, i + 1, e);
    }
}

这种方法将partition子程序与主程序写在一起,看起来更加简洁。

  • 方法二
int partition(vector<int> &nums, int left, int right) {
    int pivot = nums[left], l = left + 1, r = right;  //选取第一个元素为pivot
    while (l <= r) {
        if (nums[l] > pivot && pivot > nums[r])
            swap(nums[l++], nums[r--]);
        if (nums[r] >= pivot)
            r--;
        if (nums[l] <= pivot)
            l++;
    }
    swap(nums[r], nums[left]);
    return r;
}

void quickSort2(vector<int> &nums, int b, int e) {
    if (b < e) {
        int index = partition(nums, b, e);
        quickSort2(nums, b, index - 1);
        quickSort2(nums, index + 1, e);
    }
}

通常情况下,我们把partition子程序独立出来,这样思路更清晰。另外partition子程序在处理“第N大的数”这类问题的时候也很有帮助。

复杂性分析
当划分比较平衡,即左右两边的元素个数都接近n/2的时候,通过主定理不难得出快速排序的算法复杂度为O(nlogn)。
但如果数组本身基本有序时,如果还是选择第一个或者最后一个元素作为pivot,那么每次划分后左右两边就会极不平衡,时间复杂度就会退化为O(n^2)。可考虑采用以下方法进行优化:

  • 随机选择一个元素作为pivot,可利用语言自带的rand函数实现;
  • 选择第一个、最后一个、最中间一个三者中的中值作为pivot。
原创文章 3 获赞 0 访问量 168

猜你喜欢

转载自blog.csdn.net/hxy1996520/article/details/105764517