码迷,mamicode.com
首页 > 编程语言 > 详细

(算法)排序复习

时间:2019-07-01 00:26:22      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:result   math   逻辑   pos   sel   前端   monk   ret   有一个   

选择排序

原理: 当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]

...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

(算法)排序复习

标签:result   math   逻辑   pos   sel   前端   monk   ret   有一个   

原文地址:https://www.cnblogs.com/fangdongdemao/p/11111785.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!