zoukankan      html  css  js  c++  java
  • 快速排序

    // 快速排序
    /*
    思路

    在数组中找一个基准数(假设以数组第一个元素当基准)
    将比基准数大的放到右边,比基准数小的放到他左边,最后数组一分为二,左边都比这个数大,右边都比这个数小
    然后在这两个数组中再分别去操作


    具体操作是将第一个元素设为基准数,从右边最后一个元素开始找,找小于等于基准数的,停下来,然后从左边第一个元素开始找,
    找大于等于基准数的,停下来,然后进行交换,直到右边的和左边的指向同一个数,然后将这个数与基准数交换,此时这个数左边都比基准数大,
    右边都比基准数小。




    为什么要从右边开始找? 因为找到后要进行交换,从右边找到更小的,与基准交换后能确定更小的在左边更大的在右边



    时间复杂度


    最坏情况:
    假设数组 [1,2,3,4,5] 这样一个有序的数组,基准数是1,
    一开始从右边找小于等于1的,找到1本身,然后分为[1]和 [2,3,4,5]
    一共执行了 n+ n-1 +n-2 +...1 = (1+n)*n/2 = 1/n + 1/n2 时间复杂度是 o(n2)

    (来看最糟糕情况下的快排,当待排序的序列为正序或逆序排列时,且每次划分只得到一个比上一次划分少一个记录的子序列,注意另一个为空。)

    
    最好情况:
    假设每次第一个元素都是当前数组的中间值
    那么第一次划分2个,第二次划分四个,第三次划分8个,
    需要划分log2n次 (个数为n)

    假设每次都遍历数组所有元素,所有的遍历次数是nlogn


    */



    let arr = [3, 4, 5, 2, 1, 7, 2, 11]

    function quicksort(arr, left, right) {

    let pivot = arr[left]
    let j = right
    let i = left

    // 退出条件
    if (left >= right) return

    while (i < j) {
    while (arr[j] >= pivot && i < j) {
    j--
    }
    while (arr[i] <= pivot && i < j) {
    i++
    }
    // 现在找到了,要进行交换
    if (i < j) {
    let tmp = arr[j]
    arr[j] = arr[i]
    arr[i] = tmp
    }
    }

    // 现在要把它和pivot交换
    arr[left] = arr[i]
    arr[i] = pivot

    //交换完后在下一个数组分组里分治
    quicksort(arr, left, i - 1)
    quicksort(arr, i + 1, right)
    }

    quicksort(arr, 0, arr.length - 1)

    console.log(arr);


    ========================================
     
     
     
    最坏情况与最好情况:
     

    最坏时间复杂度 o(n2)

    当数组本身是一个有序数组时,如果以第一个元素作为pivot(枢纽、基准)

    那么,每次分的时候,都是一边一个,另一边n-1个

    需要遍历 n + n-1 + n-2 + n-3 +... + ... 1

    即1+2+3+...n = (上底+下底)*高/2 = (1+n)n/2 = O(n2)

    最好时间复杂度 o(nlogn)

    最好的情况是每次都能均匀的划分序列 

    如果第一个元素作为pivot ,每次这个pivot恰好是数组的 中间值

    那么会分成左右两边 设每层需要的时间最坏是n(也就是所有的遍历一遍),

    下面看一下每次分层后,这个一共有多少层,

    第一层是一个数组(2^0),第二层是2个数组(2^1),第三层是4个数组(2^2),第四层是8个数组(2^3)

    ... 到最后一层会有n个数组, 那么一共会有  (2^x = n ; x = logn)层               

    注: log2n 简记为 logn 因为https://www.cnblogs.com/eret9616/p/12929769.html

    所以最坏总遍历次数是层数*循环的列为 logn*n     即为 nlogn

      

    平均时间复杂度 O(nlogn)

    这个需要一些数学工具,推理过程比较复杂,记住结论就行

    复杂度图像

     
  • 相关阅读:
    虚函数和纯虚函数
    MS CRM 2011中PartyList类型字段的实例化
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(4)
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(2)
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第二部分)——IOrganizationService(二)
    MS CRM 2011 SDK 5.08已经发布
    MS CRM 2011 Q2的一些更新
    最近很忙
    Microsoft Dynamics CRM 2011最近的一些更新
    补一篇,Update Rollup 12 终于发布了
  • 原文地址:https://www.cnblogs.com/eret9616/p/9874559.html
Copyright © 2011-2022 走看看