Javascript算法系列之快速排序(Quicksort)

简介:

快速排序(Quicksort)是对冒泡排序的一种改进,是一种分而治之算法归并排序的风格

核心的思想就是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

理论上的步骤:

  1. 找到一个“支点”项目在数组中,可以是中心点,基准
  2. 在阵列中的第一项开始指针(左指针)。
  3. 在数组中的最后一个项目开始一个指针(右指针)。
  4. 而在左指针数组中的值小于枢轴值,将左指针向右(加1)。 继续,直到在左指针的值大于或等于所述枢轴值。
  5. 而在合适的指针数组中的值大于枢轴值,将右指针向左(减去1)。 继续下去,直到在正确的指针的值小于或等于所述枢轴值。
  6. 如果左指针是小于或等于右指针,然后交换的值在数组中的这些位置。
  7. 移动左指针向右由1和右指针向左之一。
  8. 如果左指针和右指针不符合,请转到步骤1。

 

原文太罗嗦了,简单的来说

  1. 在数据集之中,选择一个元素作为"基准"(pivot)。
  2. 所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
  3. 对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

 

来个实际的demo

var items = [4, 2, 6, 5, 3, 9];

具体的流程算法如下:

针对这一组数组,如何选择这个支点呢,有些算法选择第一项为支点, 这是不是最好的选择,性能最差。 一般更好地选择数组中间的支点,所以考虑5是枢轴值(数组的长度除以2)

接下来从左边拿0位置拿第一个数与支点5对比,如果4<5,那么指针的位置就偏移到1,然后2<5,一次类推

如果6>5的时候,此时左边的指针就停止移动

然后从右边的指针开始移动,也是如此,只是右边是取的大于的值,比如9>5 ,往前移位,3<5,此时也停止移动,然后交换指针对应的数值

 


第一步:选择支点 
image

 

第二步: 指针在前后开始偏移

image

 

第三步:如果4<5,继续移动左边的指针往下

image

 

第四步:如果2<5,往下,6>5停止

image

 

第五步:9>5,往前,3<5停止

image

 

第六步:交换指针指向的值

image

 

第七步:继续如上的操作,直到支点

image

 

第八部:如果指针到了支点,就停止

image

 


配合实现交换的swap的代码

function swap(items, firstIndex, secondIndex){
    var temp = items[firstIndex];
    items[firstIndex] = items[secondIndex];
    items[secondIndex] = temp;
}

 

实现的代码

复制代码
function partition(items, left, right) {
    var pivot   = items[Math.floor((right + left) / 2)],
        i       = left,
        j       = right;
    while (i <= j) {
        while (items[i] < pivot) {
            i++;
        }
        while (items[j] > pivot) {
            j--;
        }
        if (i <= j) {
            swap(items, i, j);
            i++;
            j--;
        }
    }
    return i;
}
复制代码

这个函数接受三个参数: items ,这是值进行排序的阵列, left ,这是该指数以启动左指针时,和right ,这是该指数以启动右指针。 枢轴值是通过将所确定的leftright的值,然后除以2。 因为这个值可能是一个浮点数,有必要进行一些舍入。

整个算法是循环只是一个循环。 外环确定何时所有的数组范围的项目已经被处理。 左,右指针的两个内部循环控制运动。当两个内部循环的完成,则该指针进行比较,以确定是否交换是必要的。 在交换之后,两个指针被移动,使外循环继续,在合适的地方。 该函数返回的左指针的值,因为这是用于确定从哪里开始隔间的下一次。 请记住,该分区是发生在地方,而不会产生任何额外的数组。

快速排序算法基本上通过划分整个阵列的工作原理,然后递归地分割阵列的左侧和右侧的部分,直到整个阵列被排序。

在前面的例子中,数组变[4, 2, 3, 5, 6, 9]一个分区,并返回索引后为4(左指针的最后一个席位),开始递归左右2个分割阵列

如下面的图所示

第一步:找到指针遍历的位置,确定支点

image

 

第二步:从左右指针位置开始,对比4<3,停止

image

 

第三步:因为5>3,移动右边的指针,因为3==3,停止

image

 

第四步:交换指针指向的值

image

 

第五步:依次如上处理

image

 

第六步:因为2<3,移动左边指针,因为4>3,停止

因为左边的指针超过了右边的指针,停止

image

该过程之后,该阵列变成[3, 2, 4, 5, 6, 9]和返回的索引是1,继续这样,直到所有的阵列左侧的排序。 然后相同的处理接着在右侧的阵列。 基本对数的快速排序,然后变得非常简单:

复制代码
function quickSort(items, left, right) {
    var index;
    if (items.length > 1) {
        index = partition(items, left, right);
        if (left < index - 1) {
            quickSort(items, left, index - 1);
        }
        if (index < right) {
            quickSort(items, index, right);
        }

    }
    return items;
}

// first call
var result = quickSort(items, 0, items.length - 1);
复制代码

 

快速排序通常被认为是高效,快速等特点是使用V8引擎的实现Array.prototype.sort()上有超过23个项目的数组。 对于少于23个项目,V8采用插入排序法[2]。

归并排序是快速排序的竞争对手,因为它也是高效,快捷,但有被稳定的好处。 这就是为什么Mozilla和Safari中使用它自己的执行Array.prototype.sort() 本文转自艾伦 Aaron博客园博客,原文链接:http://www.cnblogs.com/aaronjs/p/3539538.html,如需转载请自行联系原作者

相关文章
|
10月前
|
存储 监控 算法
局域网监控其他电脑的设备信息管理 Node.js 跳表算法
跳表通过分层索引实现O(logn)的高效查询、插入与删除,适配局域网监控中设备动态接入、IP映射及范围筛选等需求,相比传统结构更高效稳定,适用于Node.js环境下的实时设备管理。
343 9
|
存储 监控 JavaScript
基于布隆过滤器的 Node.js 算法在局域网电脑桌面监控设备快速校验中的应用研究
本文探讨了布隆过滤器在局域网电脑桌面监控中的应用,分析其高效空间利用率、快速查询性能及动态扩容优势,并设计了基于MAC地址的校验模型,提供Node.js实现代码,适用于设备准入控制与重复数据过滤场景。
377 0
|
运维 监控 JavaScript
内网网管软件中基于 Node.js 的深度优先搜索算法剖析
内网网管软件在企业网络中不可或缺,涵盖设备管理、流量监控和安全防护。本文基于Node.js实现深度优先搜索(DFS)算法,解析其在网络拓扑遍历中的应用。通过DFS,可高效获取内网设备连接关系,助力故障排查与网络规划。代码示例展示了图结构的构建及DFS的具体实现,为内网管理提供技术支持。
316 11
|
10月前
|
存储 监控 JavaScript
企业上网监控系统的恶意 URL 过滤 Node.js 布隆过滤器算法
布隆过滤器以低内存、高效率特性,解决企业上网监控系统对百万级恶意URL实时检测与动态更新的难题,通过概率性判断实现毫秒级过滤,内存占用降低96%,适配大规模场景需求。
478 3
|
10月前
|
存储 监控 算法
电脑管控软件的进程优先级调度:Node.js 红黑树算法
红黑树凭借O(log n)高效插入、删除与查询特性,适配电脑管控软件对进程优先级动态调度的高并发需求。其自平衡机制保障系统稳定,低内存占用满足轻量化部署,显著优于传统数组或链表方案,是实现关键进程资源优先分配的理想选择。
437 1
|
11月前
|
运维 监控 JavaScript
基于 Node.js 图结构的局域网设备拓扑分析算法在局域网内监控软件中的应用研究
本文探讨图结构在局域网监控系统中的应用,通过Node.js实现设备拓扑建模、路径分析与故障定位,提升网络可视化、可追溯性与运维效率,结合模拟实验验证其高效性与准确性。
553 3
|
监控 算法 JavaScript
基于 JavaScript 图算法的局域网网络访问控制模型构建及局域网禁止上网软件的技术实现路径研究
本文探讨局域网网络访问控制软件的技术框架,将其核心功能映射为图论模型,通过节点与边表示终端设备及访问关系。以JavaScript实现DFS算法,模拟访问权限判断,优化动态策略更新与多层级访问控制。结合流量监控数据,提升网络安全响应能力,为企业自主研发提供理论支持,推动智能化演进,助力数字化管理。
368 4
|
算法 搜索推荐
快速排序-数据结构与算法
快速排序(Quick Sort)是一种基于分治法的高效排序算法。其核心思想是通过选择基准(pivot),将数组划分为左右两部分,使得左侧元素均小于基准,右侧元素均大于基准,然后递归地对左右两部分进行排序。时间复杂度平均为 O(n log n),最坏情况下为 O(n²)(如数组已有序)。空间复杂度为 O(1),属于原地排序,但稳定性不佳。 实现步骤包括编写 `partition` 核心逻辑、递归调用的 `quickSort` 和辅助函数 `swap`。优化方法有随机化基准和三数取中法,以减少最坏情况的发生。
822 13
|
监控 算法 JavaScript
公司局域网管理视域下 Node.js 图算法的深度应用研究:拓扑结构建模与流量优化策略探析
本文探讨了图论算法在公司局域网管理中的应用,针对设备互联复杂、流量调度低效及安全监控困难等问题,提出基于图论的解决方案。通过节点与边建模局域网拓扑结构,利用DFS/BFS实现设备快速发现,Dijkstra算法优化流量路径,社区检测算法识别安全风险。结合WorkWin软件实例,展示了算法在设备管理、流量调度与安全监控中的价值,为智能化局域网管理提供了理论与实践指导。
383 3
|
算法 JavaScript 前端开发
Javascript常见算法详解
本文介绍了几种常见的JavaScript算法,包括排序、搜索、递归和图算法。每种算法都提供了详细的代码示例和解释。通过理解这些算法,你可以在实际项目中有效地解决各种数据处理和分析问题。
485 21

热门文章

最新文章