排序算法

162 阅读4分钟

参考链接:visualgo.net/zh|

冒泡排序

冒泡排序比较所有相邻的两个元素,如果第一个比第二个大,则交换他们,元素向上移动至正确的顺序,就好像气泡升至到表面一样,冒泡排序因此得名 排序算法将一串数组(一个列表)中的元素(整数,数字,字符串等)按某种顺序(增大,减小,字典顺序等)重新排列。

ezgif-3-7f47cb8c24.gif

var arrList = [11,22,33,9,49,41,26,24,39,43,46,18,41]
function bubbleSort(arr){

    const {length} = arr; //获取数组的长度
    
    for(let i = 0; i < length; i++){ //循环数组

        for(let j =0; j < length - 1 + i; j++){//从j = 1 到最后一个没有排序过元素的索引 -1

            if(arr[j] > arr[j + 1]){ //如果 左边元素 > 右边元素

                swap(arr,j,j+1) //交换(左边元素,右边元素)
            }
        }
    }
    console.log(arr)
}
function swap(array,a,b){

    const temp = array[a];

    array[a] = array[b];

    array[b]= temp;
}
bubbleSort(arrList)

选择排序

选择排序算法是一种原址比较排序算法,选择排序大致的思路是找到数据结构中的最小值并将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推

[video-to-gif output image]

var arrList = [11,22,33,9,49,41,26,24,39,43,46,18,41];
//交换位置方法
function swap(array,a,b){
    const temp = array[a];

    array[a] = array[b];

    array[b]= temp;

}

function selectionSort(arr){

    const {length} = arr;

    let indexMin;

    for(let i = 0; i < length-1; i++){//重复(元素个数-1)次

        // console.log(i)

        indexMin = i;//  把第一个没有排序过的元素设置为最小值

        for(let j = indexMin; j < length; j++){//  遍历每个没有排序过的元素

            if(arr[indexMin] > arr[j]){ //取数组第一个元素对比 [11] > [11,22,33,9,49,41,26,24,39,43,46,18,41];

                indexMin = j; //将此元素设置成为新的最小值 [11] > [9] //indexMin:3

                console.log(j)

            }

        }

        if(i !== indexMin){//第一轮遍历 i的是0 index的值是3

            swap(arr,i,indexMin) //将最小值和第一个没有排序过的位置交换

            //原数组 arr [11,22,33,9,49,41,26,24,39,43,46,18,41]

            // i 是 0, indexMin 是 3 原数组中下标 0 与 3 元素交换

            //交换过的数组 [9,22,33,11,49,41,26,24,39,43,46,18,41]

            console.log(arr)// [9, 22, 33, 11, 49, 41, 26, 24, 39, 43, 46, 18,41]

        }

    }

    console.log(arr);//排序好的数组

}

selectionSort(arrList)

插入排序

[video-to-gif output image]

var arrList = [11,22,33,9,49,41,26,24,39,43,46,18,41];

console.log('原数组数据',arrList)

function swap(array,a,b){

    const temp = array[a];

    array[a] = array[b];

    array[b]= temp;

}
function insertSort(arr){

    const {length} = arr;

    let temp;

    for(let i = 0; i < length; i++){

        temp = arr[i] //将第一个元素标记为已排序[11]

        let j = i; //“提取” 元素 j => 0 ~ 13

        // 第1次循环 0 > 0 && arr[0-0]:11 > 11 //第3次条件不成立

        // 第2次循环 1 > 0 && arr[1-1]:11 > 11 //第2次条件不成立

        // 第3次循环 2 > 0 && arr[2-1]:22 > 11 //第3次条件不成立

        // 第4次循环 3 > 0 && arr[3-1]:9 > 11 //第3次条件不成立

        while(j>0 && arr[j-1] > temp){  

            //第4次条件成立,进入while循环

            // [11,22,33,9,49,41,26,24,39,43,46,18,41]

            // arr[3]:9 = arr[2]:33  =>  [11,22,9,33,49,41,26,24,39,43,46,18,41]

            // j-- : 2

            arr[j] = arr[j - 1]

            j--

            console.log('arr',arr,'j',j)

        }

        arr[j] = temp;

    }

    console.log(arr)

}

insertSort(arrList)

归并排序

归并排序是一种分而治之算法,其思想是将原始数组切分成比较小的数组,直到每个小数组只有一个位置,接着将小数组归并成大的数组,直到最后一个排序完毕的大数组

[video-to-gif output image] 图片.png

function mergeSort(array){

    if(array.length > 1){

        const {length} = array;

        const middle = Math.floor(length / 2);

        const left = mergeSort(array.slice(0,middle));

        const right = mergeSort(array.slice(middle,length));

        console.log('left',left)

        console.log('right',right)

        array = merge(left,right)

    }

    return array;

}

function merge(left,right){

    let i = 0;

    let j = 0;

    const result = [];

    while(i < left.length && j > right.length){

        result.push(

            left[i] < right[j] ? left[i++] : right[j++]

        )

        console.log(result)

    }

    return result.concat(i < left.length ? left.slice(i) : right.slice(j));

}

mergeSort(arrList)

快速排序

[video-to-gif output image]

function quickSort(arr){

    // arr => [11,22,33,9,49,41,26,24,39,43,46,18,41]

    const {length} = arr; //13

    if(length <= 2){ //如果只有两个元素直接返回数组 arr

        return arr

    }

    // 基准

    let base = arr[0];//[11]

    let minArr = arr.slice(1).filter(item => item <= base);//取数组第一项 [11] 循环比较 [22,33,9,49,41,26,24,39,43,46,18,41] <= 11 结果为 [9]

    let maxArr = arr.slice(1).filter(item=> item > base)//取数组第一项 [11] 循环比较 [22,33,9,49,41,26,24,39,43,46,18,41] > 11 结果为 [22,33,49,41,26,24,39,43,46,18,41]                                                                                                                                                                                                                              

    return quickSort(minArr).concat(base).concat(quickSort(maxArr))

}

console.log(quickSort(arrList))

计数排序

计数排序使用一个用来存储每个元素在原始数组中出现的临时数组,在所有元素都计数完成后,临时数组已经排序好并可迭代以构建排序后的结果数组

[video-to-gif output image]

var arr = [5,7,5,4,9];
countStort(arr)
function countStort(arr){
    if(arr.length < 2){
        return arr
    }
    const maxValue = findMax(arr);
    // const maxValue = Math.max(...arr)
    const counts = new Array(maxValue+1)
    arr.forEach((item,index) => {
        if(!counts[counts]){
            counts[item] = 0
        }
        counts[item]++
    });
    let newarr = [];
    let sortIndex = 0;
    counts.forEach((item,index)=>{
        while(item>0){
            newarr[sortIndex++] = index
            item --
        }
    })
    return newarr
}
function findMax(arr){
    let max = arr[0];
    for(let i =1; i < arr.length;i++ ){
        if(arr[i]>max){
            max = arr[i]
        }
    }
}

搜索算法

顺序搜索

顺序或线性搜索是基本的搜索算法,他的机制是将每一个数据结构中的元素和我们要找的元素做比较,顺序搜索是最低效的一种算法

    function search(arr,val){

    for(let i = 0; i < arr.length; i++){

        if(arr[i] === val){

            return i

        }

    }

}

let result =   search(arrList,49)

console.log(result)
## 二分搜索

![图片.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a4a8b1133afc4e4aa90733e4b4596ee5~tplv-k3u1fbpfcp-watermark.image?)