【JavaScript】实现各类经典排序算法

1. 冒泡排序

// 冒泡排序 - Bubble sort
function bubble_sort(arr) {
    arr = arr.slice();
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j + 1 < arr.length - i; j++) {
            if (arr[j] > arr[j + 1]) {
                let tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
    return arr;
}

2. 选择排序

// 选择排序 - Select sort
function select_sort(arr) {
    arr = arr.slice();
    for (let i = 0; i < arr.length; i++) {
        let index = i;
        for (let j = i; j < arr.length; j++) {
            if (arr[j] < arr[index]) {
                index = j;
            }
        }
        let tmp = arr[i];
        arr[i] = arr[index];
        arr[index] = tmp;
    }
    return arr;
}

3. 插入排序

// 插入排序 - Insert sort
function insert_sort(arr) {
    arr = arr.slice();
    for (let i = 0; i < arr.length; i++) {
        let num = arr.splice(i, 1)[0];
        for (let j = i - 1; j >= -1; j--) {
            if (j === -1 || arr[j] < num) {
                arr.splice(j + 1, 0, num);
                break;
            }
        }
    }
    return arr;
}

4. 快速排序

// 快速排序 - Quick sort
function quick_sort(arr) {
    arr = arr.slice();
    function sort(arr, a, c) {
        if (a >= c) {
            return;
        }
        let i = a + 1;
        let j = c;
        while (i <= j) {
            if (arr[i] < arr[a]) {
                i += 1;
            } else {
                swap(arr, i, j);
                j -= 1;
            }
        }
        let b = i - 1;
        swap(arr, a, b);
        sort(arr, a, b - 1);
        sort(arr, b + 1, c);
    }
    function swap(arr, i, j) {
        let tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    sort(arr, 0, arr.length - 1);
    return arr;
}

5. 归并排序

// 归并排序 - Merge sort
function merge_sort(arr) {
    arr = arr.slice();
    function sort(arr, tmp, a, c) {
        if (a >= c) {
            return;
        }
        let b = a + parseInt((c - a) / 2);
        sort(arr, tmp, a, b);
        sort(arr, tmp, b + 1, c);
        let ai = a;
        let bi = b + 1;
        for (let i = a; i <= c; i++) {
            if (ai > b) {
                tmp[i] = arr[bi];
                bi += 1;
            } else if (bi > c) {
                tmp[i] = arr[ai];
                ai += 1;
            } else if (arr[ai] < arr[bi]) {
                tmp[i] = arr[ai];
                ai += 1;
            } else {
                tmp[i] = arr[bi];
                bi += 1;
            }
        }
        for (let i = a; i <= c; i++) {
            arr[i] = tmp[i];
        }
    }
    let tmp = new Array(arr.length);
    sort(arr, tmp, 0, arr.length - 1);
    return arr;
}

6. 堆排序

// 堆排序 - Heap sort
function heap_sort(arr) {
    arr = arr.slice();
    function sort(arr) {
        for (let root = parseInt(arr.length / 2); root >= 0; root--) {
            heap(arr, arr.length, root);
        }
        for (let size = arr.length; size > 0; size--) {
            heap(arr, size, 0);
            swap(arr, 0, size - 1);
        }
    }
    function heap(arr, size, root) {
        let large = root;
        while (large < size) {
            let left = (root * 2) + 1;
            let right = (root * 2) + 2;
            if (left < size && arr[large] < arr[left]) {
                large = left;
            }
            if (right < size && arr[large] < arr[right]) {
                large = right;
            }
            if (large !== root) {
                swap(arr, root, large);
                root = large;
            } else {
                break;
            }
        }
    }
    function swap(arr, i, j) {
        let tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    sort(arr);
    return arr;
}

7. 计数排序

// 计数排序 - Count sort
function count_sort(arr) {
    arr = arr.slice();
    let max = arr[0];
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    let counts = [];
    for (let i = 0; i <= max; i++) {
        counts.push(0);
    }
    while (arr.length !== 0) {
        let index = arr.shift();
        counts[index] += 1;
    }
    for (let i = 0; i < counts.length; i++) {
        for (let j = 0; j < counts[i]; j++) {
            arr.push(i);
        }
    }
    return arr;
}

8. 基数排序

// 基数排序 - Radix Sort
function radix_sort(arr) {
    arr = arr.slice();
    let boxs = null;
    let digit = 1;
    let isEnd = false;
    while (!isEnd) {
        boxs = [[], [], [], [], [], [], [], [], [], []];
        digit = digit * 10;
        isEnd = true;
        while (arr.length !== 0) {
            let num = arr.shift();
            let index = parseInt((num % digit) / (digit / 10));
            boxs[index].push(num);
            if (index !== 0) {
                isEnd = false;
            }
        }
        for (let i = 0; i < boxs.length; i++) {
            while (boxs[i].length !== 0) {
                let num = boxs[i].shift();
                arr.push(num);
            }
        }
    }
    return arr;
}

9. 排序测试

// 生成随机数组
function random_array(length) {
    let arr = [];
    for (let i = 0; i < length; i++) {
        let num = Math.floor(Math.random() * length);
        arr.push(num);
    }
    return arr;
}

// 验证排序结果
function check_result(arr) {
    for (let i = 1; i < arr.length; i++) {
        if (arr[i - 1] > arr[i]) {
            return false;
        }
    }
    return true;
}

// 显示排序耗时
function show_sort_time(arr, $func) {
    let ts1 = Date.now();
    arr = $func(arr);
    let ts2 = Date.now();
    if (check_result) {
        console.log("Sorting " + arr.length + " numbers "
            + $func.name + " takes " + (ts2 - ts1) + "ms")
    }
}

let arr = random_array(100_000);
show_sort_time(arr, bubble_sort); // 12121ms
show_sort_time(arr, select_sort); // 3685ms
show_sort_time(arr, insert_sort); // 9416ms
show_sort_time(arr, quick_sort); // 13ms
show_sort_time(arr, merge_sort); // 20ms
show_sort_time(arr, heap_sort); // 16ms
show_sort_time(arr, count_sort); // 593ms
show_sort_time(arr, radix_sort); // 4243ms

VisuAlgo 排序算法可视化
https://visualgo.net/zh/sorting

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值