快速排序,又称划分交换排序。以分治法为策略实现的快速排序算法。

本文主要要谈的是利用javascript实现in-place思想的快速排序

分治法:

在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。(摘自维基百科)

快速排序的思想

数组中指定一个元素作为标尺,比它大的放到该元素后面,比它小的放到该元素前面,如此重复直至全部正序排列。

快速排序分三步:

  1. 选基准:在数据结构中选择一个元素作为基准(pivot)
  2. 划分区:参照基准元素值的大小,划分无序区,所有小于基准元素的数据放入一个区间,所有大于基准元素的数据放入另一区间,分区操作结束后,基准元素所处的位置就是最终排序后它应该所处的位置
  3. 递归:对初次划分出来的两个无序区间,递归调用第 1步和第 2步的算法,直到所有无序区间都只剩下一个元素为止。

现在先说说普遍的实现方法(没有用到原地算法)

function quickSort(arr) {if (arr.length <= 1) return ;//取数组最接近中间的数位基准,奇数与偶数取值不同,但不印象,当然,你可以选取第一个,或者最后一个数为基准,这里不作过多描述var pivotIndex = Math.floor(arr.length / 2);var pivot = arr.splice(pivotIndex, 1)[0];//左右区间,用于存放排序后的数var left = [];var right = [];console.log('基准为:' + pivot + ' 时');for (var i = 0; i < arr.length; i++) {console.log('分区操作的第 ' + (i + 1) + ' 次循环:');//小于基准,放于左区间,大于基准,放于右区间if (arr[i] < pivot) {left.push(arr[i]);console.log('左边:' + (arr[i]))} else {right.push(arr[i]);console.log('右边:' + (arr[i]))}}//这里使用concat操作符,将左区间,基准,右区间拼接为一个新数组//然后递归1,2步骤,直至所有无序区间都 只剩下一个元素 ,递归结束return quickSort(left).concat([pivot], quickSort(right));
}var arr = [14, 3, 15, 7, 2, 76, 11];
console.log(quickSort(arr));
/** 基准为7时,第一次分区得到左右两个子集[ 3, 2,]   7   [14, 15, 76, 11];* 以基准为2,对左边的子集[3,2]进行划分区排序,得到[2] 3。左子集排序全部结束* 以基准为76,对右边的子集进行划分区排序,得到[14, 15, 11] 76* 此时对上面的[14, 15, 11]以基准为15再进行划分区排序, [14, 11] 15* 此时对上面的[14, 11]以基准为11再进行划分区排序, 11  [14]* 所有无序区间都只剩下一个元素,递归结束**/

通过断点调试,可得出结果。

弊端:

它需要Ω(n)的额外存储空间,跟归并排序一样不好。在生产环境中,需要额外的内存空间,影响性能。

同时,很多人认为上边的就是真正的快速排序了。 所以,在下面,很有必要的推荐in-place算法的快速排序

有关于原地算法可参考维基百科,被墙的同学,百度也差不多。

in-place

快速排序一般是用递归实现,最关键是partition分割函数,它将数组划分为两部分,一部分小于pivot,另一部分大于pivot。具体原理上边提过

function quickSort(arr) {// 交换function swap(arr, a, b) {var temp = arr[a];arr[a] = arr[b];arr[b] = temp;}// 分区function partition(arr, left, right) {/*** 开始时不知最终pivot的存放位置,可以先将pivot交换到后面去* 这里直接定义最右边的元素为基准*/var pivot = arr[right];/*** 存放小于pivot的元素时,是紧挨着上一元素的,否则空隙里存放的可能是大于pivot的元素,* 故声明一个storeIndex变量,并初始化为left来依次紧挨着存放小于pivot的元素。*/var storeIndex = left;for (var i = left; i < right; i++) {if (arr[i] < pivot) {/*** 遍历数组,找到小于的pivot的元素,(大于pivot的元素会跳过)* 将循环i次时得到的元素,通过swap交换放到storeIndex处,* 并对storeIndex递增1,表示下一个可能要交换的位置*/swap(arr, storeIndex, i);storeIndex++;}}// 最后: 将pivot交换到storeIndex处,基准元素放置到最终正确位置上
        swap(arr, right, storeIndex);return storeIndex;}function sort(arr, left, right) {if (left > right) return;var storeIndex = partition(arr, left, right);sort(arr, left, storeIndex - 1);sort(arr, storeIndex + 1, right);}sort(arr, 0, arr.length - 1);return arr;
}console.log(quickSort([8, 4, 90, 8, 34, 67, 1, 26, 17]));

分区的优化

这里细心的同学可能会提出,选取不同的基准时,是否会有不同性能表现,答案是肯定的,但,因为,我是搞前端的,对算法不是很了解,所以,这个坑留给厉害的人来填补。

复杂度

快速排序是排序速度最快的算法,它的时间复杂度是O(log n)

在平均状况下,排序n个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较.

转载于:https://www.cnblogs.com/LIUYANZUO/p/5745306.html

js实现快速排序(in-place)简述相关推荐

  1. JS实现快速排序(代码+讲解)

    OK,排序这一个篇章也快要结束了. 这一篇主要说的是快速排序,说的方式主要还是先说原理,然后再用代码来进行实现. 所谓快速排序,就是分为三步走: 第一步:选择第一个数字分离出来为基数 第二步:然后将序 ...

  2. js reduce实现中间件_简述 laravel中间件 的原理

    laravel的middleware中间件,使用了管道(pipe). 什么是管道呢? 管道类似水净化过程中的层层过滤. 中间件的意思就是说,在接下来的逻辑之前,需要的操作. 例如江河之水我们不能直接喝 ...

  3. 原生js实现快速排序

    function quickSort(arr){if(arr.length<=1){ //长度小于1时直接返回原数组return arr;}var index=Math.floor(arr.le ...

  4. js实现冒泡排序,快速排序,选择排序

    用js冒泡排序,快速排序,选择排序 1.冒泡排序 冒泡排序是比较经典的排序方法,是一种用时间换空间的排序方法.我总结了一下它的特点:(1)它的时间复杂度是:(2)每一趟相邻元素两两比较完毕就会产生最值 ...

  5. 关于js快速排序的总结

    快速排序的思想是:随机选取一个中间值,遍历数组,将数组中比这个数小的放在这个数左边,将数组中比这个数大的放在右边,直至该数组排序完成. 关于js的快速排序思路主要有两种: 第一种:递归思想,使用两个数 ...

  6. Node.js快速排序

    题目 https://leetcode-cn.com/problems/sort-an-array /*** @param {number[]} nums* @return {number[]}*/ ...

  7. html搜索框 模糊搜索,前端js模糊搜索(模糊查询)

    1.html结构: /*查询结果放ul里面*/ 2.css样式: #searchShop { line-height: 28px; text-indent: 5px; width: 180px; fl ...

  8. 试简述smtp通信的三个阶段的过程_从输入URL到页面加载的过程?《转载》

    这是我看过这个问题最完整/优质的回答了,转来分享 知乎的排版不太好,可以浏览博客原文: http://gaoxiang.ga/index.php/archives/36/​gaoxiang.ga 前言 ...

  9. css定位页面元素,页面元素定位-CSS元素基本定位

    基本定位 """属性定位 一 """ # #通过id # driver.find_element_by_css_selector(" ...

  10. 百度阿里网易大疆等大小厂前端校招面筋

    自我介绍下:某985硕士,程序媛,接触前端一年时间.从八月份开始校招面试笔试,前前后后大厂小厂也都面了挺多,不过大厂基本都被我挂完了,哭晕我,还是太菜啊.面过的公司:ThoughtWorks,大疆,阿 ...

最新文章

  1. 小学计算机知识讲课,小学信息技术说课稿《走进计算机》
  2. 2009年新计划,开始使用dotnet来开发web
  3. Luogu P4168 [Violet]蒲公英 分块
  4. 3d页游开发_大翅膀等于页游风?天谕手游扭转印象,阿云嘎同款黑翅膀最有排面...
  5. js获取上一个月、下一个月
  6. [洪流学堂]Hololens开发高级篇5:空间映射(Spatial mapping)
  7. 档案电子封装包Java类,email: Android电子邮件库(基于JavaMail封装)
  8. python数据结构-串
  9. 结对编程其实可以变变?
  10. Java编程:马踏棋盘算法(骑士周游问题)
  11. 【linux系统学习笔记】Linux系统初识
  12. arm linux 删除大量文件,ARM Linux根文件系统(Root Filesystem)的制作
  13. PROE 齿轮设计视频教程+直齿 斜齿 人字齿 内外啮齿 行星齿
  14. JS 不可逆加密后半部分,去混淆还原代码。
  15. 意在寥廓观鸿蒙 什么意思,“滴滴寒露凋芙蓉”的意思及全诗出处和翻译赏析...
  16. 宠物店小程序开发线上预约
  17. POJO JAVABEAN EJB的区别和联系
  18. 为什么大家都愿意进入外企?
  19. JAVA最新中国手机号段匹配
  20. JavaScript基础第六天数组

热门文章

  1. NOI题库--砝码称重V2(多重背包2^n拆分)
  2. FeelYourSound MelodicFlow for Mac - 旋律制作神器
  3. 在MacOS Big Sur中使用Safari 翻译功能的方法
  4. setContentView是如何把布局加上去的
  5. 照片被误删?别着急,EasyRecovery帮你找回来
  6. 《51单片机应用开发从入门到精通》——2.8 用外部中断控制灯闪烁
  7. 百度安全专家盘点:非官方购火车票渠道 几乎都不靠谱
  8. 利用Python进行数据分析(3) 使用IPython提高开发效率
  9. Android - 模块添加与编译
  10. 关于音频通信引擎接口便宜性的实验