• JavaScript中的快速排序


    1.快速排序有多重要?

    快速排序几乎可以说是目前所有排序算法中,最快的一种排序算法。(当然,没有任何一种算法在任意情况下都是最优的。比如:希尔排序确实在某些情况下可能好于快速排序,但大多数情况下,快速排序还是比较好的选择~)

    2.快速排序的思想:

    先来回忆一下冒泡排序的思路:对于未排序的各元素依次比较相邻两个元素大小关系;

                  如果左边的数大,则两元素交换位置,向右移动一个位置,比较下面两个元素;

                  当走到最右端时,最大的元素一定被放在了最右边。

        按照这个思路,从最左端重新开始,第二轮走到倒数第二个位置即可.............

    快速排序就是冒泡排序的升级版快速排序可以在一次循环中(其实是递归调用),找出某个元素的正确位置,并且该元素之后不需要任何移动。

    快速排序最重要的思想:分而治之。

    可以看到,以上是递归的处理左边的数据和右边的数据。那么问题来了?我该如何选择一个数字来进行划分呢?为什么选择65、31、81呢?接下来学习如何选择一个:枢纽

    3.快排的实现思路(我直接写在纸上了,字不好看,但知识很有意思~)

    可以看到枢纽起着至关重要的作用~~,接下来看看如何选择枢纽(尽量选择靠中间的)

    这里我的做法是:选择头、中、尾三个数,然后比较大小,选择一个中位数

    对应到上个例题中就是:left:0,   right:length-1;    center:(left+right)/2

               left:[0]    right:[8]      center:[4]

               left:23   right:72      center:76

    中位数为:72,所以就将72定位枢纽(可能这里这个数据不太好,但原理就是这么个原理~)

    接下来就将这三个数字排序之后放在对应的位置,将比枢纽小的放在第一个,比枢纽大的放在最后一个,将枢纽放在倒数第二位

    4.代码实现:

     //  快速排序代码
        // 1.选择枢纽
        ArrayList.prototype.median = function (left, right) {
          // 取出中间的位置
          var center = Math.floor((left + right) / 2)
          // 对三个数据进行判断大小,并排序
          if (this.array[left] > this.array[center]) {
            // 如果左边的数大于中间的数,则两者交换
            this.swap(left, center)
          }
          if (this.array[center] > this.array[right]) {
            // 如果中间的数大于右边的数,则两者交换
            this.swap(center, right)
          }
          if (this.array[left] > this.array[right]) {
            // 如果中间的数大于右边的数,则两者交换
            this.swap(left, right)
          }
          // 将枢纽与倒数第二个位置上的数交换
          this.swap(center, right - 1)
          // 返回枢纽
          return this.array[right - 1]
        }
        ArrayList.prototype.quickSort = function(){
          this.quick(0,this.array.length-1)
        }
        //递归函数
        ArrayList.prototype.quick = function(left,right){
          // 结束条件:当传入的left比right大时(左边的数比右边的数大时)递归结束
          if(left >= right) return
          // 获取枢纽
          var pivot = this.median(left,right)
          // 左指针,变量,用于记录当前找到的位置
          var i = left
          // 右指针
          var j = right - 1
          // 开始进行交换
          while(true){
            // 左指针向右移,碰到比枢纽大的就停住(直接从++i开始,是因为left是比枢纽小的,不用再次比较)
            while(this.array[++i] < pivot ) {}
            // 右指针向左移,碰到比枢纽小的就停住
            while(this.array[--j] > pivot ) {}
            if(i<j){
              // 如果i<j,则i与j交换(比如例题中的第三步)
              this.swap(i,j)
            }else{
              // 当i>j的时候,退出循环
              break
            }
          }
          // i和枢纽交换,此时枢纽已经找到正确位置,枢纽左边的都是小于它的,枢纽右边的都是大于它的
          // (可以参考例题中的步骤4)
          this.swap(i,right-1)
          // 分而治之,枢纽左边的
          this.quick(left,i-1)
          // 分而治之,枢纽右边的
          this.quick(i+1,right)
        }
  • 相关阅读:
    ansible使用sudo
    shell中命令作为变量使用
    for循环使用
    移动多个文件
    获取ip
    if、elif 条件判断
    python安装二进制k8s 1.11.0 一个master、一个node 查看node节点是主机名---apiserver无法启动,后来改了脚本应该可以
    (转)《黑客帝国完全解析》
    关于敏捷开发方法(Agile Software Development)的阅读笔记
    关于软件工程结对编程作业 PairProject : Elevator Scheduler(电梯调度算法的实现与测试)的总结
  • 原文地址:https://www.cnblogs.com/yaya-003/p/12660051.html
Copyright © 2020-2023  润新知