主页

排序

排序

 

冒泡排序

比较相邻的两个元素,如果前一个比后一个大,则交换位置。
第一轮把最大的元素放到了最后面。
由于每次排序最后一个都是最大的,所以之后按照步骤1排序最后一个元素不用比

1
2
3
4
5
6
7
8
9
10
11
function bubble_sort(arr) {
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0, temp; j < arr.length - i - 1; j++) {
            if (arr[j + 1] < arr[j]) {
                temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp;
            }
        }
    }
    console.log(arr);
}
bubble_sort([3, 8, 8, 4, 5, 2, 1, 1]);

  

插入排序

过程类似于将牌桌上的牌拿到手中的过程(手中的牌始终保持升序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function insert_sort(arr) {
    // [0, i-1] 是手中的牌,[i, arr.length-1]是牌桌上的牌
    // 一开始手中有一张牌 arr[0]
    for (let i = 1; i < arr.length; i++) { // 始终保证 [0, i-1]的元素是升序
        let val = arr[i]; // 从牌桌上拿一张牌
        let right = i - 1;
        // 将其插入到手中牌的适当位置(手中较大的牌整体右移一位,如果手中牌均小,则不移动)
        while (right >= 0 && arr[right] > val) {
            arr[right + 1] = arr[right];
            right--;
        }
        arr[right + 1] = val;
    }
    console.log(arr);
}
insert_sort([3, 8, 8, 4, 5, 2, 1, 1]);

  

快速排序

核心就在递归

1. 划分: arr[i...j](包括arr[i] 和 arr[j])排序,随意取[i,j]中的一点p(如 p = (i + j) /2)则 将其划分为三段:arr[i...p-1]  arr[p]  arr[p+1...j]

2.  递归排序:将arr[i...p-1]中所有大于arr[p]的元素变换到 arr[p+1...j] 中,将 arr[p+1...j]中所有小于 arr[p]的元素变换到 arr[i...p-1]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function quick(arr, i, j) { // 范围  [i, j]
    if (i < j) {
        let q = split(arr, i, j); // 确保 范围 [i, q) 的值小于等于arr[q]  范围 [q+1, j]的值大于arr[q]
        quick(arr, i, q - 1);
        quick(arr, q + 1, j);
    }
}
 
function split(arr, i, j) { // 范围  [i, j]
    let val = arr[j], temp;
    let minAreaRight = i - 1; // 区域[i, minAreaRight]的值均小于等于val
    for (let k = i; k < j; k++) { // 遍历完成后区域 [minAreaRight+1, k] 的值均大于val
        if (arr[k] <= val) {
            minAreaRight++;
            temp = arr[k]; arr[k] = arr[minAreaRight]; arr[minAreaRight] = temp;
        }
    }
    minAreaRight++;
    temp = arr[j]; arr[j] = arr[minAreaRight]; arr[minAreaRight] = temp;
    return minAreaRight;
}
 
quick([3, 8, 8, 4, 5, 2, 1, 1], 0, arr.length - 1); 

 

归并排序

1. 划分:将数组从中间划分为两部分,分别调用自身进行排序

2. 合并:将两段排好序的数组合并为一个排好序的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function merge_sort(arr, i, j) { // [i, j]
    if (i < j) {
        const mid = Math.floor(i + (j - i) / 2);
        merge_sort(arr, i, mid);
        merge_sort(arr, mid + 1, j);
        merge(arr, i, mid, j);
    }
}
 
function merge(arr, i, mid, j) { // [i, mid] 和 [mid+1, j] 分别已是升序
    const leftArr = arr.slice(i, mid + 1), leftIndex = 0;
    const rightArr = arr.slice(mid + 1, j + 1), rightIndex = 0;
    leftArr.push(Number.MAX_SAFE_INTEGER);
    rightArr.push(Number.MAX_SAFE_INTEGER);
    for (let k = i; k <= j; k++) {
        if(leftArr[leftIndex] <= rightArr[rightIndex]){
            arr[k] = leftArr[leftIndex];
            leftIndex++;
        }else{
            arr[k] = rightArr[rightIndex];
            rightIndex++;
        }
    }
}
let arr = [3, 8, 8, 4, 5, 2, 1, 1];
merge_sort(arr, 0, arr.length - 1);
console.log(arr);

  

aa

 

aa

 

posted @   平凡人就做平凡事  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示