数据结构与算法——排序3(快速排序)

一、🐶 快速排序的原理

  • 分区: 从数组中任意选择一个基准,所有比基准小的元素放到基准前面,比基准大的元素放到基准的后面
  • 递归:递归地对基准前后的子数组进行分区

快排实现方式一代码如下(不考虑空间消耗):

js 复制代码
Array.prototype.quickSort = function () { 
    const rec = (arr) => { 
       // 预防数组是空的或者只有一个元素, 当所有元素都大于等于基准值就会产生空的数组
       if(arr.length === 1 || arr.length === 0) { return arr; }
       const left = [];
       const right = [];
       //以第一个元素作为基准值   
       const mid = arr[0];
       //小于基准值的放左边,大于基准值的放右边
       for(let i = 1; i < arr.length; ++i) { 
           if(arr[i] < mid) { 
               left.push(arr[i]);
           } else { 
               right.push(arr[i]);
           }
       }
        //递归调用,最后放回数组    
       return [...rec(left),mid,...rec(right)];
    };
    const res = rec(this);
    res.forEach((n,i) => { this[i] = n; })
}

const arr = [2,3,4,5,3,1];
arr.quickSort();
console.log(arr);

总结:简明易懂,好理解,好写,适合面试的时候手撸代码。

时间复杂度
  • 最好时间复杂度为O(nlog₂n)
  • 最坏时间复杂度为O(n²)
  • 平均时间复杂度为O(nlog₂n)
空间复杂度

需要额外的left和right临时空间所以空间复杂度为O(nlog₂n)

稳定性

代码第8行约定以第一个元素作为基准值,代码11-15行约定,当数据等于mid的时候放到right区间,所以相同元素位置前后不会改变。属于稳定的排序算法

快排实现方式二代码如下(不占用额外的空间消耗):

js 复制代码
function quickSort(arr, low, high) {
  if (low < high) {
    let pivotposition = partition(arr, low, high);
    quickSort(arr, low, pivotposition-1);
    quickSort(arr, pivotposition+1, high);
  }  
} 

function partition(arr, low, high) {
  let temp = arr[low];
  while(low < high) {
    // 此时左边位置为空,所以从右边去找,如果arr[high] >= temp移动指针接着往前找
    while(low < high && arr[high] >= temp){
      high--;
      continue;
    }
    // 此时左边位置为空,从右边去找,如果arr[high] < temp,则把它赋值给左边,此时右边的位置为空,跳出循环,重头再来
    while(low < high && arr[high] < temp){
      arr[low] = arr[high];
      low++;
      break;
    }
    // 此时右边为空,去左边找,找到arr[low] <= temp,移动指针接着往后找
    while(low < high && arr[low] <= temp){
      low++;
      continue;
    }
    // // 此时右边为空,去左边找,找到arr[low] > temp,把它赋值到右边,跳出循环,重头再来
    while(low < high && arr[low] > temp){
      arr[high] = arr[low];
      high--;
      break;
    }
  }
  arr[low] = temp;
  return low;
}
  • 我们遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。
  • 经过这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivot,后面的 q+1 到 r 之间是大于 pivot 的。
  • 据分治、递归的处理思想,我们可以用递归排序下标从 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直到区间缩小为 1,就说明所有的数据都有序了。
时间复杂度
  • 分区均衡,最好时间复杂度为O(nlog₂n)
  • 分区不均衡,最坏时间复杂度为O(n²)
  • 平均时间复杂度为O(nlog₂n)
空间复杂度

只需要一个temp空间,所以空间复杂度为O(1)

稳定性

涉及到左右位置的交换,所以排序过程中2个相同的数位置会交换,是不稳定的排序算法。

相关推荐
m51277 分钟前
LinuxC语言
java·服务器·前端
烦躁的大鼻嘎7 分钟前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
C++忠实粉丝24 分钟前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
用户37791362947551 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法
福大大架构师每日一题1 小时前
文心一言 VS 讯飞星火 VS chatgpt (396)-- 算法导论25.2 1题
算法·文心一言
Myli_ing1 小时前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
EterNity_TiMe_1 小时前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
dr李四维1 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
机器学习之心1 小时前
一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测
算法·lstm·transformer·北方苍鹰算法优化·多变量回归预测·ngo-transformer
yyt_cdeyyds2 小时前
FIFO和LRU算法实现操作系统中主存管理
算法