前端面试-JS数组排序几种实现方式

56 阅读2分钟

前言: 本篇文章整理汇总:冒泡排序、选择排序、插入排序、快速排序四种排序实现;

1、交换元素代码下:

ArrayList.prototype.swap = (m, n) => {
    let temp = this.arrayList[m]
    this.arrayList[m] = this.arrayList[n]
    this.arrayList[n] = temp
}

一、冒泡排序:

    // 冒泡排序思路:从前向后两两比较,较大的一个放在右边;
    // 比较次数O(n^2)、交换次数O(n^2)
    ArrayList.prototype.bubbleSort = () => {
        let arrayLength = this.arrayList.length
        for(let j = arrayLength - 1; j >= 0; j--) {
            for (let i = 0; i < j; i++) {
                if(this.arrayList[i] > this.arrayList[i + 1]) {
                    this.swap(i, i + 1)
                }
            }
        }
    }

二、选择排序

    // 选择排序思路:找到从前往后遍历长度内最小值的下标,每次找到后,按顺序放置到数组前面
    // 第一次遍历: 从下标0开始到数组最后面,找到最小值的下标,与下标0进行交换;
    // 第二次遍历:从下标1开始,找到最小值的下标,与下标1进行交换;
    // ...
    // 比较次数O(n^2)、交换次数O(n)
    ArrayList.prototype.selectSort = () => {
        let arrayLength = this.arrayList.length
        for(let j = 0; j < arrayLength; j++) {
            let min = j
            for(let i = min + 1 ; i< arrayLength; i++) {
                if(this.arrayList[min] > this.arrayList[i]) {
                    min = i
                }
            }
            this.swap(min, j)
        }
    }

三:插入排序

    // 插入排序思路:将一个记录插入到已经排好序的有序表里面
    // 案例: 13254
    // 比较 1 和 3,无需移动 -> 13254
    // 比较 3 和 2, 3与2交换位置;2与1比较,无需移动 -> 12354
    // 比较 3 和 5, 无需移动 -> 12354
    // 比较 5 和 4, 5与4交换位置;4与3比较,无需移动 -> 12345
    ArrayList.prototype.insertSort = () => {
        let arrayLength = this.arrayList.length
        for(let i = 1;i<arrayLength;i++) {
            let temp = this.arrayList[i]
            let j = i
            while(j > 0 && this.arrayList[j - 1] > temp) {
                this.arrayList[j] = this.arrayList[j - 1]
                j--
            }
            this.arrayList[j] = temp
        }
    }

四、快速排序

    // 快速排序思想:冒泡排序每次循环是把当前最大的值找出来放在最右边;
    // 快速排序是冒泡排序的优化:每次将数字直接放在最终的正确的位置;
    // 选取枢纽,找出数组两头和中间数字作比较,选出三个数字的中间值作为枢纽,
    // 此枢纽放于最右侧减一的位置,
    // 三个数字的最大值放置于数组的最右侧;代码如下:
    ArrayList.prototype.median = (left, right) => {
        let center = Math.floor((left + right) / 2);
        if(this.arrayList[left] > this.arrayList[center]) {
            this.swap(left, center);
        }
        if(this.arrayList[left] > this.arrayList[right]) {
            this.swap(left, right);
        }
        if(this.arrayList[center] >  this.arrayList[right]) {
            this.swap(center, right);
        }
        this.swap(center, right - 1);

        return this.arrayList[right - 1];
    }
    // 找到枢纽后,遍历数据,将比枢纽大的值放在枢纽右侧,比枢纽值小的放置于左侧;
    ArrayList.prototype.quickSort = () => {
        this.quick(0, this.arrayList.length - 1)
    }
    // 递归
    ArrayList.prototype.quick = (left, right) => {
        if(left >= right) return
        // 枢纽值
        let center = this.median(left, right)
        let i = left
        let j = right - 1
        while (i < j) {
            while(this.arrayList[++i] < center) {
            }
            while(this.arrayList[--j] > center) {
            }
            if( i < j) {
                this.swap(i , j)
            } else {
                break
            }
        }

        console.log({ i })
        this.swap(i, right - 1)
        console.log(this.arrayList)


        // 递归
        this.quick(left, i - 1)
        this.quick(i + 1 , right)

    };