• 快速排序


    // 快速排序
    /*
    思路

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


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




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



    时间复杂度


    最坏情况:
    假设数组 [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)

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

    复杂度图像

     
  • 相关阅读:
    【转载】C#中List集合使用Remove方法移除指定的对象
    【转载】C#中List集合使用RemoveAt方法移除指定索引位置的元素
    【转载】C#中ToArray方法将List集合转换为对应的数组
    【转载】C#中List集合使用RemoveRange方法移除指定索引开始的一段元素
    【转载】C#中Add方法将往List集合末尾添加相应元素对象
    【转载】C#中List集合使用Reverse方法对集合中的元素进行倒序反转
    【转载】C#中通过Distinct方法对List集合进行去重
    【转载】 C#中使用CopyTo方法将List集合元素拷贝到数组Array中
    【转载】 C#中通过Where方法查找出所有符合条件的元素集合
    Android -- Camera聚焦流程
  • 原文地址:https://www.cnblogs.com/eret9616/p/9874559.html
Copyright © 2020-2023  润新知