JS排序算法

99 阅读2分钟

1.冒泡排序

    // 1.第一次循环数组,循环n-1次
    // 2.第二次循环数组,循环n-1-i次,此循环中两两对比
    function bubbleSort(arr) {
        var n = arr.length
        var temp
        for (let i = 0; i < n - 1; i++) {
            for (let j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j + 1]
                    arr[j + 1] = arr[j]
                    arr[j] = temp
                }
            }
        }
        return arr;
    }
    var arr = [5, 6, 1, 4, 3, 9, 2, -1]
    console.log(bubbleSort(arr))

2.快速排序

    // 取数组中间的数,将数组分为左右两部分,分别排序,循环递归
     function QuickSort(arr) {
        if (arr.length <= 1) {
            return arr
        }
        let left = [], right = []
        let start = 0, end = arr.length - 1
        let middleIndex = Math.floor(arr.length / 2)
        let middle = arr.splice(middleIndex, 1)[0]
        for (let i = 0; i < arr.length; i++) {
            if (arr[i] < middle) {
                left.push(arr[i])
            } else if (arr[i] > middle) {
                right.push(arr[i])
            }
        }
        return QuickSort(left).concat([middle], QuickSort(right))
    }
    console.log(QuickSort(arr))

3.插入排序

    // 循环找到插入的元素,将他和他前面的数据,从后向前一次对比
    // 如果当前值小于他前一个的值,则当前值和前一个值交换,知道不下于且前面的值大于等于0为止,
    // 此刻当前值就在他前面值的后一位
    function insertSort(arr) {
        let current, preIndex
        for (let i = 1; i < arr.length; i++) {
            current = arr[i]
            preIndex = i - 1
            while (preIndex >= 0 && current < arr[preIndex]) {
                arr[preIndex + 1] = arr[preIndex]
                preIndex--
            }
            arr[preIndex + 1] = current
        }
        return arr
    }
    console.log(insertSort(arr))

4.希尔排序

    // 插入排序--希尔排序
    // 增量排序
    // 第一步:先将数组分为gap增量:[5,9],[6,2],[1,-1],[4,8],[3,-2]=>[5,9],[2,6],[-1,1],[4,8],[-2,3]=>[5,2,-1,4,-2,9,6,1,8,3]
    // 第二步:将数组再次差分为gap执行[5,2,-1,4,-2,9,6,1,8,3]=>[5,-1,-2,6,8],[2,4,9,1,3]=>[-2,-1,5,6,8],[1,2,3,4,9]=>[-2,1,-1,2,5,3,6,4,8,9]
    // 第三步:gap/2==1,[-2,1,-1,2,5,3,6,4,8,9]=>[-2,-1,1,2,3,4,5,6,8,9]


    function ShellSort(arr) {
        // 第一个for的作用:将数组分为arr.length/2组,增量排序{n/2 ,(n/2)/2,...,1}
        for(var gap=Math.floor(arr.length/2);gap>0;gap=Math.floor(gap/2)) {
            // 对每一个gap进行插入排序
            console.log('==========')
            console.log(gap)            // ==> 5,2,1
            // 每次循环体中就开始排序
            for(let i=gap;i<arr.length;i++) {
                let j = i,
                current = arr[i]
                while(j-gap>=0&&current<arr[j-gap]) {
                    arr[j] = arr[j-gap]
                    j = j-gap;
                }
                arr[j] = current
            }
        }
        return arr
    }
    console.log(ShellSort(arr))

5.选择排序

    1.第一次for循环,定义一个最小值
    2.第二次for循环,将最小值和遍历值对比,如果遍历值小于最小值,则遍历值赋值给最小值,最小值赋值给遍历值
 
    var arr = [5, 6, 1, 4, 3, 9, 2, -1]

    function SelectionSort(arr) {
        let minIndex, temp;
        for (let i = 0; i < arr.length - 1; i++) {
            minIndex = i
            for (let j = i + 1; j < arr.length; j++) {
                if (arr[minIndex] > arr[j]) {
                    minIndex = j
                }
            }
            temp = arr[i]
            arr[i] = arr[minIndex]
            arr[minIndex] = temp
        }
        return arr
    }
    console.log(SelectionSort(arr))

6.堆排序

    var arr = [4,6,8,5,9]
    var len;
    // 堆排序
    // 第一步,建立一个二叉树大顶堆模型
    function BuildMaxHeap(arr) {
        console.log('最初的arr='+arr)
        len = arr.length
        for(let i=Math.floor(len/2);i>=0;i--) {
            // 排序
            Heapify(arr,i)
        }
        return arr

    } 
    // 二叉树排序
    function Heapify(arr,i) {
        let left = 2*i+1,
            right = 2*i+2,
            largest = i

        // 当前节点和其父节点对比
        if (left<len && arr[left]>arr[largest]) {
            largest = left
        }
        if (right<len && arr[right]>arr[largest]) {
            largest = right
        }
        if (largest != i) {
            swap(arr,i,largest)
            Heapify(arr,largest)
        }
    }
    // 调换位置
    function swap(arr,i,j) {
        var temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
    }

    function HeapSort(arr) {
        BuildMaxHeap(arr)
        for (var i = arr.length-1;i>0 ;i--) {
            swap(arr,0,i)
            len--
            Heapify(arr,0)
        }
        return arr
    }

    console.log(HeapSort(arr))

7.归并排序

    // 1.分:先将数组差分开两份,递归拆分,知道拆分结束,只剩一组数据
    // 2.治:将数组排序

    function MergeSort(arr) {
        if (arr.length<2) {
            return arr
        }
        // 拆分
        let middle = Math.floor(arr.length/2)
        let leftArr = arr.slice(0,middle)
        let rightArr = arr.slice(middle,arr.length)
        // 递归拆分
        let leftArrSort = MergeSort(leftArr)
        let rightArrSort = MergeSort(rightArr)

        // 合并

        return Merge(leftArrSort,rightArrSort)
    }

    function Merge(left,right) {
        let result = []
        while(left.length && right.length) {
            if (left[0]>=right[0]) {
                result.push(right.shift())
            } else {
                result.push(left.shift())
            }
        }
        while(left.length) {
            result.push(left.shift())
        }
        while(right.length) {
            result.push(right.shift())
        }

        return result;
    }   

    console.log(MergeSort(arr))

计数排序

    function CountingSort(arr) {
        // 创建一个新数组,用于存储排序的值,此数组中key为原数组中的value,value值为原数组value的个数
        let newArr = new Array(arr.length).fill(0)
        console.log(newArr)
        for(let value of arr) {
            newArr[value]++
        }       


        arr = []

        for(let i=0;i<newArr.length;i++) {
            for(let j=newArr[i];j>0;j--) {
                arr.push(i)
            }
        }
        return arr
    }
    
    这里有一个缺点,就是原数组中不能负数

持续更新中....