Javascript进阶排序算法

88 阅读3分钟

1. 希尔排序 (Shell Sort) 

算法介绍: 希尔排序是插入排序的一种改进,通过先将数组分成若干子序列进行插入排序,然后逐渐减小子序列间的间隔,直至为1,完成整个数组的排序。这种方法能够将较远距离的元素也逐步移至更接近其最终位置,减少了数据交换的次数,提高了排序效率。

function shellSort(arr) {
    let n = arr.length;
    for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
        for (let i = gap; i < n; i++) {
            let temp = arr[i];
            let j;
            for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
                arr[j] = arr[j - gap];
            }
            arr[j] = temp;
        }
    }
    return arr;
}

// 使用示例
console.log(shellSort([22, 11, 99, 88, 9, 70, 2, 75, 65]));

2. 计数排序 (Counting Sort)

算法****介绍: 计数排序是非比较排序算法,适用于一定范围内的整数排序。它通过计算每个值的出现次数,然后根据计数累加的结果来确定每个元素的正确位置,从而将输入数组转换为输出数组。计数排序的时间复杂度为O(n+k),其中n是数组长度,k是数值范围。

function countingSort(arr) {
    let max = Math.max(...arr);
    let min = Math.min(...arr);
    let range = max - min + 1;
    let count = new Array(range).fill(0);
    let output = new Array(arr.length);

    arr.forEach((num) => count[num - min]++);
    
    for (let i = 1; i < count.length; i++) {
        count[i] += count[i - 1];
    }

    for (let i = arr.length - 1; i >= 0; i--) {
        output[count[arr[i] - min] - 1] = arr[i];
        count[arr[i] - min]--;
    }

    return output;
}

// 使用示例
console.log(countingSort([4, 2, 2, 8, 3, 3, 1]));

3. 桶排序 (Bucket Sort)

算法****介绍: 桶排序是一种分布式排序算法,它将元素分布到若干个桶中,每个桶再分别排序(通常使用插入排序或其他适合的排序算法)。桶排序要求输入数据均匀分布在一定范围内。其效率取决于桶的划分和桶内排序算法的选择,最好情况下的时间复杂度为O(n+k),其中n是数组长度,k是桶的数量。

function bucketSort(arr, bucketSize = 5) {
    if (arr.length === 0) return arr;
    let minValue = Math.min(...arr);
    let maxValue = Math.max(...arr);
    let bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;
    let buckets = Array.from({length: bucketCount}, () => []);

    arr.forEach(num => {
        buckets[Math.floor((num - minValue) / bucketSize)].push(num);
    });

    let sortedArr = [];
    buckets.forEach(bucket => {
        insertionSort(bucket);
        sortedArr = sortedArr.concat(bucket);
    });

    return sortedArr;
}

function insertionSort(arr) {
    for (let i = 1; i < arr.length; i++) {
        let key = arr[i];
        let j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}

// 使用示例
console.log(bucketSort([0.42, 0.32, 0.33, 0.52, 0.37, 0.47, 0.51]));

4. 基数排序 (Radix Sort) 

算法****介绍: 基数排序是一种非比较排序算法,适用于整数或字符串的排序。它通过逐位对元素进行排序,从最低有效位(个位)开始,到最高有效位。排序过程中使用桶来收集相同位值的元素,然后再将这些桶连接起来形成新的数组。重复此过程,直到所有位都被处理完。基数排序的时间复杂度通常为O(nk),其中n是数组长度,k是数字的最大位数。

function radixSort(arr) {
    const getMax = (arr) => Math.max(...arr.map(String).map(x => x.length));
    const digitCount = getMax(arr);
    
    for (let k = 0; k < digitCount; k++) {
        let buckets = Array.from({length: 10}, () => []);
        arr.forEach(num => {
            let digit = Math.floor(Math.abs(num) / Math.pow(10, k)) % 10;
            buckets[digit].push(num);
        });
        arr = [].concat(...buckets);
    }
    
    return arr;
}

// 使用示例
console.log(radixSort([170, 45, 75, 90, 802, 24, 2, 66]));

ok,相对于上次分享的经典算法,今天的算是进阶篇吧,总的排序算法应该就上面这些了