zoukankan      html  css  js  c++  java
  • (算法)排序复习

    选择排序

    原理: 当i=0,首先找到最小的元素放在起始的位置,然后i=1,再然后找到最小的元素放到最左i=1的位置,然后i=2,...

    动画演示

    const SelectSort = arr => {
        if (arr == null || arr.length < 2) {
            return
        }
        for (let i = 0; i < arr.length-1; i++) {
            let minIndex = i
            for (let j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex=j
                }
            }
            if (minIndex !== i) {
                swap(arr, i, minIndex)
            }
        }
        return arr
    }
    const swap = (arr, i, j) => {
        arr[i] = arr[i] ^ arr[j]
        arr[j] = arr[i] ^ arr[j]
        arr[i] = arr[i] ^ arr[j]
    }
    let arr = [1, 2, 10, 3, 4, 5, 6]
    console.log(SelectSort(arr))
    

    插入排序

    const InsertSort = arr => {
        if (arr == null || arr.length < 2) {
            return
        }
        for (let i = 1; i < arr.length; i++) {
            for (let j = i-1;j>=0&&arr[j]>arr[j+1];j--) {
                swap(arr,j,j+1)
            }
        }
        return arr
    }
    const swap = (arr, i, j) => {
        arr[i] = arr[i] ^ arr[j]
        arr[j] = arr[i] ^ arr[j]
        arr[i] = arr[i] ^ arr[j]
    }
    let arr = [1, 2, 10, 3, 4, 5, 6]
    console.log(InsertSort(arr))
    

    归并排序

    动画

    逻辑解释

    • 首先,讲数字分割成两份区域,在讲数字分割成两份区域,只到每块区域只有一个元素(这个过程是递归过程)

      const mergeSort=array=>{
          if(array.length<2) return array;
          let mid = Math.floor(array.length / 2)
          let left = array.slice(0, mid);
          let right = array.slice(mid);
          return merge(mergeSort(left), mergeSort(right))
      }
      举例说明入栈
      [9, 3,4,5, 10,9, 6, 4]
      [9, 3,4,5] | [10,9,6, 4]
      [9,3] | [4,5] | [10,9] | [6,4]
      [9] [3]|[4] [5] |[10][9] | [6] [4]
      
    • 截下来,讲分割的每块区域进行合并组合

    [9] [3]|[4] [5] |[10][9] | [6] [4]
    出栈
    [3,9]|[4,5] |[9,10]|[4,6]
    [3,4][5,9]
    [3,4,5,9]   | [4,6,9,10]
    //left[0]<arr[0]
    const merge=(left,right)=>{
        let result=[];
        while (left.length > 0 && right.length > 0) {
            if (left[0] < right[0]) {
                result.push(left.shift())
            }else{
                result.push(right.shift())
            }
        }
        /*把长度不一样的连接起来*/
        return result.concat(left).concat(right)
    }
    

    桶排序

    计数排序

    动画

    逻辑

    • 计算出数组中的最大值
    • 建立最大值加一的数组且数组中每一个数为0
    • 新的数组进行值得累积
    • 下面的打下断点就懂了
    const bucketSort = arr => {
        if (arr == null || arr.length < 2) {
            return arr
        }
        let max = Math.max(...arr)
        let bucket = Array.from({length: max + 1}, v => 0)
        let oArr = []
        for (let i = 0; i < arr.length; i++) {
            //值得累积
            bucket[arr[i]]++
        }
        for (let i = 0; i < bucket.length; i++) {
            while (bucket[i]-- > 0) {
                oArr.push(i)
            }
        }
        return oArr
    }
    console.log(bucketSort([10, 9, 7, 6, 3]))
    

    基数排序

    动画

    //获取每位的数字位数
    const getDigit = (x, d) => {
        let a = Math.pow(10, d)
        return Math.floor(x / a) % 10
    }
    
    const radixSort=(arr)=> {
        //最大位数
        let maxDigit = String(Math.max(...arr)).length
        let counter = []
    
        for (let i = 0; i < maxDigit; i++) {
            for (let j = 0; j < arr.length; j++) {
                let bucket = getDigit(arr[j], i)
                if (counter[bucket] == null) {
                    counter[bucket] = []
                }
                counter[bucket].push(arr[j])
            }
            let pos = 0
            for (let j = 0; j < counter.length; j++) {
                let value = null
                if (counter[j] != null) {
                    while ((value = counter[j].shift()) != null) {
                        arr[pos++] = value
                    }
                }
            }
        }
        return arr
    }
    
    let arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    
    console.log(radixSort(arr, 2))
    //[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
    

    自己修改版(不知道会不会写错,因为我自己写错了,所以还是改成前端看起来比较顺眼的)

    //获取每位的数字位数
    const getDigit = (x, d) => {
        let a = Math.pow(10, d)
        return Math.floor(x / a) % 10
    }
    const radixSort = (arr) => {
        let maxDigit = String(Math.max(...arr)).length
        let counter = Array.from({length: 10}, () => [])
        for (let i = 0; i < maxDigit; i++) {
            for (let j = 0; j < arr.length; j++) {
                let a = getDigit(arr[j], i)
                counter[a].push(arr[j])
            }
            let b=0;
            counter.forEach(val=>{
                while (val.length > 0) {
                    arr[b++]=val.shift()
                }
            })
        }
        return arr
    }
    
    let arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    console.log(radixSort(arr))
    //[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
    

    #############################################################################################################################...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

  • 相关阅读:
    CISCO设备的一些硬件知识
    引用 DOS查QQ好友IP(另附入侵方法)
    【转】端口入侵常用工具分析
    修改CentOS默认yum源为国内yum镜像源
    使用Runtime类运行本地可执行文件
    英汉小词典 java随机存取文件流应用 version1.0
    8086/8088汇编过程练习 实现登录界面及其验证
    批处理伪加密
    快速启动中【显示桌面】的还原方法
    批处理字符串偏移指针
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/11111785.html
Copyright © 2011-2022 走看看