手写 “快速排序”

在我们写算法中,如果需要高效的、原地的排序算法,这时候我们就可以用到快速排序

概念

快速排序(Quick Sort)是一种常用的排序算法,用于将一组数据按照一定的顺序进行排列。它的 基本思想 是通过分治的策略将原始数组分割成较小的子数组,然后递归地对子数组进行排序,最终将这些子数组合并起来得到有序数组。

这个算法的 “快速” 体现在以下几个方面:

  • 快速的平均时间复杂度: 在平均情况下,快速排序的时间复杂度为O(nlogn),性能非常优秀。
  • 快速的排序过程: 快速排序采用了分而治之的策略,通过不断地分割和排序来实现快速排序,因此排序的过程相对较快。
  • 快速的原地排序: 快速排序通常是原地排序的,不需要额外的存储空间。

总的来说,快速排序是一种高效的、原地的排序算法,虽然在最坏情况下时间复杂度可能较高,但在实际应用中,它的性能仍然非常出色。

那么它排序的步骤呢 (算法描述)

  1. 选择一个基准值(pivot),通常选择第一个元素作为基准值
  2. 将数组中小于等于基准值的元素放到基准值的左边,大于基准值的元素放到右边,基准值所在的位置通常称为分区点(pivot position)
  3. 递归地对基准值左右两侧的子数组进行快速排序
  4. 重复上述步骤,直到所有的子数组都变得很小,排序完成

快速排序的关键在于分区操作,即如何将小于等于基准值和大于基准值的元素分开。一般情况下,可以使用双指针法或者递归实现来进行分区操作。

快速排序的时间复杂度为O(nlogn),
在平均情况下性能很好,
但最坏情况下可能达到O(n^2)。
然而,由于其原地排序和非稳定性,快速排序在实际应用中仍然被广泛使用

function quickSort(arr, left, right):
    if left < right:
        pivotIndex = partition(arr, left, right) // 获取基准值的位置
        quickSort(arr, left, pivotIndex - 1) // 对基准值左边的子数组进行快速排序
        quickSort(arr, pivotIndex + 1, right) // 对基准值右边的子数组进行快速排序

function partition(arr, left, right):
    pivot = arr[left] // 选择第一个元素作为基准值
    i = left + 1
    j = right

    while i <= j:
        // 找到左边第一个比基准值大的元素
        while i <= j and arr[i] <= pivot:
            i = i + 1
        // 找到右边第一个比基准值小的元素
        while i <= j and arr[j] > pivot:
            j = j - 1
        if i <= j:
            swap(arr, i, j) // 交换左右两个元素

    swap(arr, left, j) // 将基准值放到正确的位置上
    return j // 返回基准值的位置

function swap(arr, i, j):
    temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp

这个伪代码描述了快速排序的基本思想和分区操作。你可以根据这个描述来实现快速排序算法。

实现

function quickSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }

  const pivot = arr[0]; // 选择第一个元素作为基准值
  const left = [];
  const right = [];

  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) {
      left.push(arr[i]); // 比基准值小的放在左边
    } else {
      right.push(arr[i]); // 比基准值大的放在右边
    }
  }

  return [...quickSort(left), pivot, ...quickSort(right)]; // 递归处理左右两部分,并将结果合并
}

// 测试
const arr = [3, 6, 8, 10, 1, 2, 1];
const sortedArr = quickSort(arr);
console.log(sortedArr); // 输出排序后的数组

这段代码实现了快速排序算法。在这个示例中,我们选择数组中的第一个元素作为基准值(pivot),然后将数组中比基准值小的元素放到左边,比基准值大的元素放到右边,最后递归地对左右两部分进行排序,直到每个子数组的长度都不大于1。

function quickSort(arr, left = 0, right = arr.length - 1) {
  if (left >= right) {
    return;
  }

  const pivot = partition(arr, left, right); // 找到基准值的位置
  quickSort(arr, left, pivot - 1); // 递归处理左边的子数组
  quickSort(arr, pivot + 1, right); // 递归处理右边的子数组
}

function partition(arr, left, right) {
  const pivotValue = arr[left]; // 选择第一个元素作为基准值
  let i = left + 1;
  let j = right;

  while (i <= j) {
    while (i <= j && arr[i] < pivotValue) {
      i++; // 找到左边第一个比基准值大的元素
    }
    while (i <= j && arr[j] > pivotValue) {
      j--; // 找到右边第一个比基准值小的元素
    }
    if (i <= j) {
      [arr[i], arr[j]] = [arr[j], arr[i]]; // 交换左右两个元素
      i++;
      j--;
    }
  }

  [arr[left], arr[j]] = [arr[j], arr[left]]; // 将基准值放到正确的位置上
  return j; // 返回基准值的位置
}

// 测试
const arr = [3, 6, 8, 10, 1, 2, 1];
quickSort(arr);
console.log(arr); // 输出排序后的数组

这种实现方式与上面的示例有所不同,它使用了双指针的方式来找到基准值的位置,并且是在原数组上进行操作的。

无论哪种实现方式,快速排序算法的核心思想都是通过分治的策略将问题规模逐步缩小,最终得到一个有序的结果。希望这能帮助你更好地理解快速排序算法的实现过程。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
快速排序是一种常用的排序算法,它采用分治的思想。下面是使用JavaScript手写快速排序的代码: ```javascript function quickSort(arr) { if (arr.length <= 1) { return arr; } const pivot = arr < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return [...quickSort(left), pivot, ...quic #### 引用[.reference_title] - *1* [js快速排序的实现代码](https://download.csdn.net/download/weixin_38500948/14903739)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [手写快速排序(JavaScript)](https://blog.csdn.net/sinat_41696687/article/details/118732731)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [JavaScript手写快速排序](https://blog.csdn.net/qq_40026070/article/details/106838994)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值