JavaScript常见算法

54 阅读3分钟

排序算法

冒泡算法

时间复杂度:O(n^2)

// 冒泡排序
(function() {
    let arrs = new Array(10).fill(1).map(item => parseInt(Math.random(item) * 100))
    function swap(arr, i, j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
    function sort(arr) {
        for(let i = 0; i < arr.length; i++) {
            for (let j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
        return arr;
    }
    console.log(sort([...arrs]));
    
})();

鸡尾酒算法

定向冒泡排序,鸡尾酒搅拌排序,搅拌排序(也可以视作选择排序的一种变形),涟漪排序,来回排序或者快乐小时排序,是冒泡排序的一种变形。

// 来回排序
(() => {
    let arrs = new Array(7).fill(1).map(item => parseInt(Math.random(item) * 100))
    function swap(arr, i, j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
    function sort(arr) {
        for(let i = 0; i < Math.floor(arr.length/2); i++) {
            for(let j = i; j < arr.length - 1 - i; j ++) {
                if (arr[j+1] < arr[j]) {
                    swap(arr, j+1, j)
                }
            }
            for(let k = arr.length - i; k > i; k--) {
                if (arr[k-1] > arr[k]) {
                    swap(arr, k-1, k)
                }
            }
        }
        return arr
    }
    console.log(sort([...arrs]));
})()

插入排序

时间复杂度:O(n^2)

// 插入排序
(function() {
    let arrs = new Array(10).fill(1).map(item => parseInt(Math.random(item) * 100))
    function swap(arr, i, j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
    function sort(arr) {
        for(let i = 1; i < arr.length; i++) {
            for (let j = i; j > 0; j--) {
                if (arr[j] < arr[j-1]) {
                   swap(arr, j, j - 1);
                }
            }
        }
        return arr;
    }
    console.log(sort([...arrs]));
    
})();

希尔排序

时间复杂度:O(n^(1.3—2)) 优化的插入排序,又叫最小增量排序

// 希尔排序
(function() {
    let arrs = new Array(10).fill(1).map(item => parseInt(Math.random(item) * 100))
    function swap(arr, i, j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
    function sort(arr, size = 3) {
        if (size < 3) {
            size = 3;
        }
        let increment = 1;
        while (increment<arr.length/size) {
            increment = increment * size + 1;
        } 
        while (increment > 0) {
            for(let i = increment; i < arr.length; i+=increment) {
                for (let j = i; j > 0; j-=increment) {
                    if (arr[j] < arr[j-increment]) {
                       swap(arr, j, j - increment);
                    }
                }
            }
            increment = Math.floor(increment/size);
        }
        return arr;
    }
    console.log(sort([...arrs],3));
    
})();

选择排序

时间复杂度:O(n^2)

// 选择排序
(function() {
    let arrs = new Array(10).fill(1).map(item => parseInt(Math.random(item) * 100))
    function swap(arr, i, j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
    function sort(arr) {
        for (let i = 0; i < arr.length; i++) {
            let minIndex = i;
            for (let j = i; j < arr.length - 1; j++) {
                if (arr[minIndex] > arr[j+1]) {
                    minIndex = j+1;
                }
            }
            if (minIndex !== i) {
                swap(arr, minIndex, i);
            }
        }
        return arr;
    }
    console.log(sort([...arrs]));
})();

快速排序

时间复杂度:O(nlogn)

// 快速排序
(function() {
    let arrs = new Array(10).fill(1).map(item => parseInt(Math.random(item) * 100))
    function swap(arr, i, j) {
        if (i === j) return
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
    function getMiddleIndex(arr, begin, end) {
        let middleValue = arr[begin];
        let beginIndex = begin + 1;
        let endIndex = end;
        while(beginIndex < endIndex) {
            while(beginIndex < endIndex && arr[beginIndex] <= middleValue) beginIndex++;
            while(beginIndex < endIndex && arr[endIndex] >= middleValue) endIndex--;
            swap(arr, beginIndex, endIndex);
        }
        if (arr[endIndex] > middleValue) endIndex--;
        swap(arr, begin, endIndex);
        return endIndex;
    }
    function quickSort(arr, begin, end) {
        if (begin >= end) return arr;
        let middle = getMiddleIndex(arr, begin, end);
        quickSort(arr, begin, middle - 1);
        quickSort(arr, middle + 1, end);
        return arr
    }
    function sort(arr) {
        return quickSort(arr, 0, arr.length-1);
    }
    console.log(sort([...arrs]));
})();

堆排序

时间复杂度:O(n*log2n)

// 堆排序
(() => {
    let arrs = new Array(10).fill(1).map(item => parseInt(Math.random(item) * 100))
    function swap(arr, i, j) {
        if (i === j) return
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
    function buildMaxStack(arr) {
        // 查找完全二叉树最后一个带有子节点的父节点
        // 【0,1,2,3,4,5,6】
        //       0
        //   1       2
        // 3   4   5   6
        for (var i = Math.floor(arr.length / 2) - 1; i >= 0; i--) {
            getMaxStack(arr, i, arr.length);
        }
    }
    function getMaxStack(arr, i, len) {
        let maxIndex = i;
        let left = i * 2 + 1;
        let right = i * 2 + 2;
        if (left < len && arr[left] > arr[maxIndex]) {
            maxIndex = left;
        }
        if (right < len && arr[right] > arr[maxIndex]) {
            maxIndex = right;
        }
        if (maxIndex !== i) {
            swap(arr, maxIndex, i);
            getMaxStack(arr, maxIndex, len);
        }
    }
    function sort(arr) {
        var len = arr.length;
        buildMaxStack(arr);
        while (len > 0) {
            swap(arr, 0, len - 1);
            len--;
            getMaxStack(arr, 0, len); 
        }
        return arr;
    }
    console.log(sort([...arrs]));
})()