快速排序 QuickSort

1. 基本思想

快速排序的基本思想是基于分治法的。

  • 在待排序数组中选取一个元素作为基准,假设以第一个元素为基准。

  • 每趟排序都能确定基准的位置。找到基准在数组中最终存放的位置。左边是所有比该元素小的值,右边是所有比该元素大的值。

  • 然后再分别对左边和右边两部分递归排序。直到每部分只有一个元素时停止排序。

适用场景

只适用于 顺序结构 (也就是数组),不能对链式结构排序。

时间复杂度

平均复杂度:O(nlogn),最好复杂度:O(nlogn),最坏复杂度:O(n^2)

空间复杂度

空间复杂度 :O(logn)

2. 代码实现(java)

public void sort(int[] array) {
    quickSort(array, 0, array.length - 1);
}

// 对区间是[low, high]的数组进行排序,一轮排完之后,确定了第一个元素的位置
public void quickSort(int[] array, int low, int high) {
    if (low >= high) return;   // 终止条件
    // 找到第一个元素(阈值)在最终的排序数组中的位置
    // 将区间 [0,len-1] 之间按阈值划分为 <阈值, >阈值 两部分
    int pos = getPosition(array, low, high);
    quickSort(array, low, pos - 1);  // 对 <阈值 的部分排序
    quickSort(array, pos + 1, high);  // 对 >阈值 的部分排序
}

public int getPosition(int[] array, int low, int high) {
    int tmp = array[low];   // 以第一个元素作为基准
    while (low < high) {
        // 从后向前找到比基准小的数
        while (low < high && array[high] >= tmp) high--;
        array[low] = array[high];  // 把array[high]移到前面
        // 从前向后找到比基准大的数
        while (low < high && array[low] <= tmp) low++;
        array[high] = array[low];  // 把array[low]移到后面
    }
    array[low] = tmp;   // 把基准放在最终的位置上
    return low;  // 返回最终的位置
}

3. 代码说明

1)quickSort() 中会有两个参数 lowhigh ??

因为在排序过程中,排序的数组的起始位置和终止位置是变化,而不是 0(array.length-1) 不变的。

2)quickSort 终止条件为什么是 low >= high ,而不是 low > high ??

low == high 时,表明,此时数组中只有一个元素。数组中只有一个元素时,它在最终排好序的数组中

位置是和当前位置一样的,不需要进行排序。

3)在 getPosition() 中为什么是 while (low < high) ,而不是 while (low <= high)??

low == high 时,也就是找到了基准最终在排好序的数组中的位置。所以,需要跳出循环,把最终位置返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
快速排序QuickSort)是一种高效的排序算法,它基于分治策略。该算法首先选择一个元素作为基准值(pivot),然后将待排序数组按照基准值分成两个子数组,一边是所有小于基准值的元素,另一边是所有大于等于基准值的元素。然后对两个子数组分别递归地进行快速排序,最后将两个子数组合并起来即可得到完整的有序数组。 以下是使用C++实现快速排序的代码: ```cpp void quickSort(vector<int>& nums, int left, int right) { if (left >= right) return; // 递归终止条件 int pivot = nums[left]; // 选择第一个元素作为基准值 int i = left, j = right; 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, left, i - 1); // 递归地对左半部分进行快速排序 quickSort(nums, i + 1, right); // 递归地对右半部分进行快速排序 } ``` 其中,`nums`表示待排序数组,`left`和`right`表示当前子数组的左右边界(初始时应为0和`nums.size()-1`)。我们首先选择第一个元素作为基准值,然后使用双指针i和j在数组中进行一趟快速排序,将小于基准值的元素放入左半部分,将大于等于基准值的元素放入右半部分。最后将基准值放入合适的位置,并递归地对左右两个子数组进行快速排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值