前端数据结构与算法之排序算法

550 阅读7分钟

前言:

前端时间,上班的时候比较闲,将《数据结构与算法javascript描述》过了一遍。在这期间脑海中刻入了一个排序算法的方法,一直在脑中回旋,久久挥之不去。那个排序算法大概是这样描述的——在数组中去选择一个基准值,将这个值与数组中的其他值做比较,将比它大的值放在后边,将比它小的值放在它的前边。(一个模糊的记忆)为了寻找这句话对应的究竟是哪个排序算法,就好好将排序的算法都敲了一遍,在此做一个简单的记录。

冒泡排序:

  1. 基本定义:

使用这种排序算法时,数据值会像气泡一样从数组的一端漂浮到另一端。假设正在将一组数字按照升序排列,较大的值会浮动到数组的右侧,而较小的值则会浮动到数组的左侧。之所以会产生这种现象是因为算法会多次在数组中移动,比较相邻的数据,当左侧值大于右侧值时将它们进行交换。

  1. 动画演示:

冒泡排序.gif 3. 实现思路:

1. 比较所有相邻元素,如果第一个比第二个大,则交换它们。
2. 一轮下来,可以保证最后一个数是最大的。
3. 执行len-1轮,就可以完成排序。
4. 里面那一层需要减去外部排好序的那一层的个数。
  1. 实现方式:
let arr = [1,8,3,6,2,1,8,9];
let len = arr.length;
// 循环所有的元素
for(let j = 0; j < len; j++) {
    // 循环内部未排好序的数据
    for(let i = 0; i < len - j; i++) {
        // 如果第一个数比第二个数大
        if(arr[i] > arr[i + 1]) {
           // 如果条件成立,则将这两个数的位置互换
           let temp = arr[i];
           arr[i] = arr[i + 1];
           arr[i + 1] = temp;
        }
    }
    console.log(`当前行的排序:${arr}`);
}
console.log(arr);
  1. 函数封装:
// 冒泡排序
function bubblingAsc(arr) {
    let len = arr.length;
    for (let i = 0; i <= len - 1; i++) {
        for (let j = 0; j <= len - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                let tmep = arr[j]
                arr[j] = arr[j + 1]
                arr[j + 1] = tmep
            }
        }
        // console.log(`第${i + 1}次排序:${arr}`)
    }
    return arr
}
  1. 时间复杂度与空间复杂度:
一个循环的时间复杂度为O(n),如果是两个循环叠加则用乘法,所以冒泡排序的时间复杂度为: O(n)*O(n) = O(n^2)
因为所有的排序都是对一维数组的排序,所以空间复杂度恒等于O(n)

选择排序

  1. 基本定义:

从数组的开头开始,将第一个元素和其他元素进行比较。检查完所有元素后,最小的元素会被放到数组的第一个位置,然后算法会从第二个位置继续。这个过程一直进行,当进行到数组的倒数第二个位置时,所有的数据便完成了排序。

  1. 动画演示: 选择排序.gif
  2. 实现思路:
1. 声明一个最小值
2. 从左到右依次循环,假设当前值为最小值
3. 用最小值与其他值(它后面的其他所有元素)进行比较
4. 如果其他值小于最小值,则其他值才是最小值,将其索引赋值给最小值
5. 如果最小值与当前值的索引不相等,则将最小值与当前值互换位置
  1. 实现方式:
let arr = [5,4,3,2,1];
let len = arr.length;
let min;
for(let i = 0; i < len; i++) {
    min = i;
    for(let j = i + 1; j < len; j++) {
      if(arr[j] < arr[min]) {
        min = j;
      }
    }
    if (min !== i) {
        let temp = arr[i];
        arr[i] = arr[min];
        arr[min] = temp;
    }
}
console.log(arr);
  1. 函数封装:
function selectSort (arr) {
    let len = arr.length;
    let min; // 建一个最小值
    for (let i = 0; i < len; i++) {
        min = i // 从左到右依次循环,假设当前值为最小值
        for(let j = i + 1; j < len; j++) { // 用当前值与其他值(它后面的其他所有元素)进行比较
            if(arr[j] < arr[min]) { // 如果其他值小于当前值,则后其他值才是最小值,将其索引赋值给最小值
                min = j
            }
            console.log('当前值:' + arr[i], '其他值:' + arr[j], '最小值:' + arr[min]);
        }
        // 如果最小值与当前值的索引不相等,则将最小值与当前值互换位置
        if(min != i) {
            let tmep = arr[i]; 
            arr[i] = arr[min];
            arr[min] = tmep;
        }
    }
    return arr
}
  1. 时间复杂度与空间复杂度:
一个循环的时间复杂度为O(n),如果是两个循环叠加则用乘法,所以冒泡排序的时间复杂度为: O(n)*O(n) = O(n^2)
因为所有的排序都是对一维数组的排序,所以空间复杂度恒等于O(n)

插入排序

  1. 基本定义:

从数组的第二个位置开始,依次往前进行比较,如果比它大则将这个比它大的数往后排,将这个值插入到小于或等于这个值的位置。

  1. 动画演示:

插入排序.gif 3. 实现思路:

1. 从第二个值开始循环;
2. 如果第一个值大于第二个值,则将第一个值插入到第二个值的位置,如果小于则不作任何操作
3. 此处逻辑为第一个值如果大于或等于第二个值,则交换位置,如果小于则位置不变
  1. 实现方式:
let arr = [5,7,1,3,2];
for(let i = 1; i <= arr.length - 1; i++) {
    let temp = arr[i];
    let j = i;
    while(j > 0) {
        if(arr[j - 1] >= temp) {
            arr[j] = arr[j - 1];
        } else {
            break;
        }
        j--
    }
    arr[j] = temp;
}
console.log(arr);
  1. 函数封装:
function insertSort (arr) {
    let len = arr.length;
    for(let i = 1; i <= len - 1; i++) {
        let temp = arr[i];
        let j = i;
        while(j > 0) {
            if(arr[j - 1] >= temp) {
                arr[j] = arr[j - 1];
            } else {
                break;
            }
            j--
        }
        arr[j] = temp;
    }
    return arr
}
  1. 时间复杂度与空间复杂度:
一个循环的时间复杂度为O(n),如果是两个循环叠加则用乘法,所以冒泡排序的时间复杂度为: O(n)*O(n) = O(n^2)
因为所有的排序都是对一维数组的排序,所以空间复杂度恒等于O(n)

基本排序算法的耗时比较:

  1. 随机数组;

我们这块儿需要做的是对10个元素,100个元素,1000个元素,甚至10000个元素进行算法程序的耗时比较。此时如果还像之前那样自己定一个数组,然后再进行排序的话,就单单写数据都会写疯。在此面对不同的需求与应用场景我们必须采用不同的做法来应对,于是生成随机数组的函数就此诞生。

  1. 函数具体实现:(暂时只对数字排序进行测试)
// 生成min-max的随机数
function randomNumber(min, max) {
    return Math.floor(Math.random() * (max - min) + min);
}
// 生成随机数字写入数组
function setNumber(len) {
    let arr = []
    for (let i = 0; i <= len - 1; i++) {
        arr.push(randomNumber(0, len))
    }
    return arr
}
  1. 将以上的函数整合成一个类:
    class arraySort {
        constructor (len) {
            this.arr = this.setNumber(len)
            this.len = this.arr.length;
        }
        // 冒泡排序
        bubblingAsc () {
            const timestart = new Date().getTime();
            for(let i = 0; i <= this.len - 1; i++) {
                for(let j = 0; j <= this.len - 1 - i; j++) {
                    // 左右两个值进行比较,如果左边比右边的值大,则交换位置
                    if(this.arr[j] > this.arr[j + 1]) {
                        let tmep = this.arr[j]
                        this.arr[j] = this.arr[j + 1]
                        this.arr[j + 1] = tmep
                    }
                }
                // console.log(`第${i + 1}次排序:${this.arr}`)
            }
            const timeEnd = new Date().getTime();
            // 时长
            const duration = timeEnd - timestart
            console.log(`冒泡排序:当有${this.len}个元素,程序执行时长: ${duration}`)
            return this.arr
        }
        // 选择排序
        selectSort () {
            const timestart = new Date().getTime();
            let min; // 建一个最小值
            for (let i = 0; i <= this.len - 1; i++) {
                min = i // 从左到右依次循环,假设当前值为最小值
                for(let j = i + 1; j <= this.len - 1; j++) { // 用当前值与其他值(它后面的其他所有元素)进行比较
                    if(this.arr[j] < this.arr[min]) { // 如果其他值小于当前值,则后其他值才是最小值,将其索引赋值给最小值
                        min = j
                    }
                    // console.log('当前值:' + this.arr[i], '其他值:' + this.arr[j], '最小值:' + this.arr[min]);
                }
                // 将最小值与当前值互换位置-实际上是将最小值放到数组第一个位置,然后算法会从第二个位置继续。
                let tmep = this.arr[i]; 
                this.arr[i] = this.arr[min];
                this.arr[min] = tmep;
            }
            const timeEnd = new Date().getTime();
            // 时长
            const duration = timeEnd - timestart
            console.log(`选择排序:当有${this.len}个元素,程序执行时长: ${duration}`)
            return this.arr
        }
        // 插入排序
        insertSort () {
            const timestart = new Date().getTime();
            for(let i = 1; i <= this.len - 1; i++) {
                let temp = this.arr[i]; // 第二个元素的值
                let j = i;
                while(j > 0) {
                    if(this.arr[j - 1] >= temp) {
                        // 如果第二个值大于第一个值,则第二个值等于第一个值
                        this.arr[j] = this.arr[j - 1];
                    } else {
                        break;
                    }
                    j--
                }
                // 此处逻辑为第二个值如果大于或等于第一个值,则交换位置,如果小于则位置不变
                this.arr[j] = temp;
            }
            const timeEnd = new Date().getTime();
            // 时长
            const duration = timeEnd - timestart
            console.log(`插入排序:当有${this.len}个元素,程序执行时长: ${duration}`)
            return this.arr
        }
        // 生成min-max的随机数
        randomNumber(min, max) {
            return Math.floor(Math.random() * (max - min) + min);
        }
        // 生成随机数字写入数组
        setNumber(len) {
            let arr = []
            for (let i = 0; i <= len - 1; i++) {
                arr.push(this.randomNumber(0, len))
            }
            return arr
        }
    }
  1. 测试用例: 代码:10
    let arr = new arraySort(10);
    console.log(arr.bubblingAsc())
    console.log(arr.selectSort())
    console.log(arr.insertSort())

结果:

    冒泡排序:当有10个元素,程序执行时长: 0
    [0, 1, 1, 1, 1, 3, 3, 4, 6, 7]
    选择排序:当有10个元素,程序执行时长: 0
    [0, 1, 1, 1, 1, 3, 3, 4, 6, 7]
    插入排序:当有10个元素,程序执行时长: 0
    [0, 1, 1, 1, 1, 3, 3, 4, 6, 7]

代码: 100

    let arr = new arraySort(100);
    console.log(arr.bubblingAsc())
    console.log(arr.selectSort())
    console.log(arr.insertSort())

结果:

    冒泡排序:当有100个元素,程序执行时长: 1
    选择排序:当有100个元素,程序执行时长: 0
    插入排序:当有100个元素,程序执行时长: 0

代码:1000

    let arr = new arraySort(1000);
    console.log(arr.bubblingAsc())
    console.log(arr.selectSort())
    console.log(arr.insertSort())

结果:

    冒泡排序:当有1000个元素,程序执行时长: 5
    选择排序:当有1000个元素,程序执行时长: 3
    插入排序:当有1000个元素,程序执行时长: 0

代码:10000

    let arr = new arraySort(10000);
    console.log(arr.bubblingAsc())
    console.log(arr.selectSort())
    console.log(arr.insertSort())

结果:

    冒泡排序:当有10000个元素,程序执行时长: 202
    选择排序:当有10000个元素,程序执行时长: 78
    插入排序:当有10000个元素,程序执行时长: 2

综上所述:插入排序在元素个数相同的情况下,在基本排序中的执行速度是最快的!

归并排序:

  1. 基本定义:

把一系列排好序的子序列合并成一个大的完整有序序列。

  1. 动画演示:

归并排序.gif 3.实现思路:

1. 将数组进行二分,递归分到最小的单个元素为止;
2. 将单个元素进行比较元素大小,对其进行排序
3. 将排好序的数据进行合并,最终合并成原始数据排好序的数组

4.代码实现:

    const arr = [1,3,8,9,10,4,6,94,3];
    function mergeSort (arr) {
        if (arr?.length <= 1) {
            return arr
        }
        let mid = Math.floor(arr?.length/2);
        let left = arr.slice(0, mid);
        let rigth = arr.slice(mid);
        return merge(mergeSort(left), mergeSort(rigth))
    }
    function merge(left, rigth) {
        let temp = [];
        while (left?.length && rigth?.length) {
            if (left[0] < rigth[0]) {
                temp.push(left.shift());
            } else {
                temp.push(rigth.shift());
            }
        }
        return [...temp, ...left, ...rigth]
    }
    console.log(mergeSort(arr));// [1, 3, 3, 4, 6, 8, 9, 10, 94]
  1. 时间复杂度与空间复杂度
时间复杂度:递归二分的时间复杂度为o(logN),循环的时间复杂度为o(n),嵌套则将时间复杂度相乘o(logN)*o(n)

快速排序:

  1. 基本定义:

这个算法首先要在列表中选择一个元素作为基准值。数据排序围绕基准值进行。将列表中小于基准值的元素移到数组底部,将大于基准值的元素移到数组顶部。

  1. 动画演示:

快排.gif 3. 实现思路:

1. 将数组的第一个值设置为基准值,如果大于基准值,则写入右侧,如果小于基准值则写入左侧。
2. 将排好序的数组与基准值进行合并
  1. 具体实现:
    function quickSort (list) {
        if (!list?.length) {
            return []
        }
        let left = [];
        let rigth = [];
        let pivot = list[0];
        for (let i = 1; i < list?.length; i++) {
            if (list[i] > pivot) {
                rigth.push(list[i]);
            } else {
                left.push(list[i]);
            }
        }
        return [...quickSort(left), pivot, ...quickSort(rigth)];

    }
    let arr = [8,7,9,5,6,1];
    console.log(quickSort(arr)); // [1, 5, 6, 7, 8, 9]
  1. 时间复杂度与空间复杂度
时间复杂度:递归的时间复杂度为o(logN),循环的时间复杂度为o(n),嵌套则将时间复杂度相乘o(logN)*o(n)

注:希尔排序的嵌套层级太深了,时间复杂度太高,不做讨论

sort方法(工作中肯定是用内置的排序方法啦!)

  1. sort方法的应用场景:
1. 普通数组排序(如果是数字正常排序,如果是字母则根据首字母排序,那如果是汉字呢???)
2. 数组对象排序(根据数组对象中的某个字段进行排序)
  1. 测试用例的生成:

测试用例要包括数字,字母,单词(根据单词首字母进行排序),数组对象。(自测应该从多维度,多角度,多种情况进行测试,才能将bug的出现概率降到最低!)

class arraySort {
    constructor (len) {
        this.arr = this.setLetter(len)
        this.len = this.arr.length;
    }
    // 生成min-max的随机数
    randomNumber(min, max) {
        return Math.floor(Math.random() * (max - min) + min);
    }
    // 生成随机数字写入数组
    setNumber(len) {
        let arr = []
        for (let i = 0; i <= len - 1; i++) {
            arr.push(this.randomNumber(0, len))
        }
        return arr
    }
    // 生成随机字母
    setLetter(len) {
        let letterArr = [];
        for (var i = 0; i < len; i++) {
            letterArr[i] = String.fromCharCode(this.randomNumber(65, 91));
        }
        return letterArr;
    }
    // 自定义英语单词(生成随机的单词太过麻烦,未进行此操作)
    setWord(){
        return ['my', 'word', 'apple']
    }
    // 自定义数组对象
    setArrObj() {
        return [{id: 1, name: 'zhangsan'},{id: 4, name: 'lisi'}, {id: 2, name: 'wanger'}]
    }
}
  1. 测试用例
  1. 数字
class arraySort {
          constructor (len) {
              this.arr = this.setNumber(len)
              this.len = this.arr.length;
          }
          // 生成min-max的随机数
          randomNumber(min, max) {
              return Math.floor(Math.random() * (max - min) + min);
          }
          // 生成随机数字写入数组
          setNumber(len) {
              let arr = []
              for (let i = 0; i <= len - 1; i++) {
                  arr.push(this.randomNumber(0, len))
              }
              return arr
          }
          // 生成随机字母
          setLetter(len) {
              let letterArr = [];
              for (var i = 0; i < len; i++) {
                  letterArr[i] = String.fromCharCode(this.randomNumber(65, 91));
              }
              return letterArr;
          }
          // 自定义英语单词(生成随机的单词太过麻烦,未进行此操作)
          setWord(){
              return ['my', 'word', 'apple']
          }
          // 自定义数组对象
          setArrObj() {
              return [{id: 1, name: 'zhangsan'},{id: 4, name: 'lisi'}, {id: 2, name: 'wanger'}]
          }
          sort(type = 'asc') {
              return this.arr.sort((a,b) => {
                if(type == 'asc') return a - b
                else if(type == 'desc') return b - a
              })
          }
      }
      
      // 数字:(升序)
      let arr = new arraySort(10);
      console.log(arr.sort()); //  [0, 0, 1, 3, 3, 5, 6, 9, 9, 9]-生成的随机数组,每次数字都不一样
      // 数字:(降序)
      console.log(arr.sort('desc')); // [9, 9, 9, 6, 5, 3, 3, 1, 0, 0]
  1. 字母
class arraySort {
          constructor (len) {
              this.arr = this.setLetter(len)
              this.len = this.arr.length;
          }
          // 生成min-max的随机数
          randomNumber(min, max) {
              return Math.floor(Math.random() * (max - min) + min);
          }
          // 生成随机数字写入数组
          setNumber(len) {
              let arr = []
              for (let i = 0; i <= len - 1; i++) {
                  arr.push(this.randomNumber(0, len))
              }
              return arr
          }
          // 生成随机字母
          setLetter(len) {
              let letterArr = [];
              for (var i = 0; i < len; i++) {
                  letterArr[i] = String.fromCharCode(this.randomNumber(65, 91));
              }
              return letterArr;
          }
          // 自定义英语单词(生成随机的单词太过麻烦,未进行此操作)
          setWord(){
              return ['my', 'word', 'apple']
          }
          // 自定义数组对象
          setArrObj() {
              return [{id: 1, name: 'zhangsan'},{id: 4, name: 'lisi'}, {id: 2, name: 'wanger'}]
          }
          // 数字排序
          sort(type = 'asc') {
              return this.arr.sort((a,b) => {
                if(type == 'asc') return a - b
                else if(type == 'desc') return b - a
              })
          }
          // 字母排序
          sortLetter(type = 'asc') {
            return this.arr.sort((a,b) => {
              if(type == 'asc') return a.charCodeAt(0) - b.charCodeAt(0)
              else if(type == 'desc') return b.charCodeAt(0) - a.charCodeAt(0)
            })
          }
      }
      
      // 字母:(升序)
      let arr = new arraySort(10);
      console.log(arr.sortLetter()); //  ['C', 'D', 'D', 'E', 'G', 'O', 'P', 'R', 'T', 'T']-生成的随机数组,每次字母都不一样
      // 字母:(降序)
      console.log(arr.sortLetter('desc')); // ['T', 'T', 'R', 'P', 'O', 'G', 'E', 'D', 'D', 'C']
  1. 单词:
      class arraySort {
          constructor (len) {
              this.arr = this.setWord()
              // this.len = this.arr.length;
          }
          // 生成min-max的随机数
          randomNumber(min, max) {
              return Math.floor(Math.random() * (max - min) + min);
          }
          // 生成随机数字写入数组
          setNumber(len) {
              let arr = []
              for (let i = 0; i <= len - 1; i++) {
                  arr.push(this.randomNumber(0, len))
              }
              return arr
          }
          // 生成随机字母
          setLetter(len) {
              let letterArr = [];
              for (var i = 0; i < len; i++) {
                  letterArr[i] = String.fromCharCode(this.randomNumber(65, 91));
              }
              return letterArr;
          }
          // 自定义英语单词(生成随机的单词太过麻烦,未进行此操作)
          setWord(){
              return ['my', 'word', 'apple']
          }
          // 自定义数组对象
          setArrObj() {
              return [{id: 1, name: 'zhangsan'},{id: 4, name: 'lisi'}, {id: 2, name: 'wanger'}]
          }
          // 数字排序
          sort(type = 'asc') {
              return this.arr.sort((a,b) => {
                if(type == 'asc') return a - b
                else if(type == 'desc') return b - a
              })
          }
          // 字母和单词(根据首字母)排序
          sortLetter(type = 'asc') {
            return this.arr.sort((a,b) => {
              if(type == 'asc') return a.charCodeAt(0) - b.charCodeAt(0)
              else if(type == 'desc') return b.charCodeAt(0) - a.charCodeAt(0)
            })
          }
      }
      
            // 单词:(升序)
      let arr = new arraySort();
      console.log(arr.sortLetter()); //  ['apple', 'my', 'word']
      // 单词:(降序)
      console.log(arr.sortLetter('desc')); //  ['word', 'my', 'apple']
  1. 数组对象:
      class arraySort {
          constructor (len) {
              this.arr = this.setArrObj()
              // this.len = this.arr.length;
          }
          // 生成min-max的随机数
          randomNumber(min, max) {
              return Math.floor(Math.random() * (max - min) + min);
          }
          // 生成随机数字写入数组
          setNumber(len) {
              let arr = []
              for (let i = 0; i <= len - 1; i++) {
                  arr.push(this.randomNumber(0, len))
              }
              return arr
          }
          // 生成随机字母
          setLetter(len) {
              let letterArr = [];
              for (var i = 0; i < len; i++) {
                  letterArr[i] = String.fromCharCode(this.randomNumber(65, 91));
              }
              return letterArr;
          }
          // 自定义英语单词(生成随机的单词太过麻烦,未进行此操作)
          setWord(){
              return ['my', 'word', 'apple']
          }
          // 自定义数组对象
          setArrObj() {
              return [{id: 1, name: 'zhangsan'},{id: 4, name: 'lisi'}, {id: 2, name: 'wanger'}]
          }
          // 数字排序
          sort(type = 'asc') {
              return this.arr.sort((a,b) => {
                if(type == 'asc') return a - b
                else if(type == 'desc') return b - a
              })
          }
          // 字母和单词(根据首字母)排序
          sortLetter(type = 'asc') {
            return this.arr.sort((a,b) => {
              if(type == 'asc') return a.charCodeAt(0) - b.charCodeAt(0)
              else if(type == 'desc') return b.charCodeAt(0) - a.charCodeAt(0)
            })
          }
          // 数组对象排序
          sortArrObj(key,valueType = 'number', type = 'asc') {
            return this.arr.sort((a,b) => {
              if (valueType == 'number') {
                if(type == 'asc') return a[key] - b[key]
                else if(type == 'desc') return b[key] - a[key]
              } else if (valueType == 'word') {
                if(type == 'asc') return a[key].charCodeAt(0) - b[key].charCodeAt(0)
                else if(type == 'desc') return b[key].charCodeAt(0) - a[key].charCodeAt(0) 
              }
            })
          }
      }
      
      let arr = new arraySort();
      // 此处专为json便于查看
      // // 数组对象:(根据id升序)
      console.log(JSON.stringify(arr.sortArrObj('id'))); //  [{"id":1,"name":"zhangsan"},{"id":2,"name":"wanger"},{"id":4,"name":"lisi"}]
      // // 数组对象:(根据id降序)
      console.log(JSON.stringify(arr.sortArrObj('id', 'desc'))); //  [{"id":4,"name":"lisi"},{"id":2,"name":"wanger"},{"id":1,"name":"zhangsan"}]
      // 数组对象:(根据name升序)
      console.log(JSON.stringify(arr.sortArrObj('name', 'word'))); //  [{"id":4,"name":"lisi"},{"id":2,"name":"wanger"},{"id":1,"name":"zhangsan"}]
      // 数组对象:(根据name降序)
      console.log(JSON.stringify(arr.sortArrObj('name', 'word', 'desc'))); //  [{"id":1,"name":"zhangsan"},{"id":2,"name":"wanger"},{"id":4,"name":"lisi"}]
  1. 不传参和传参有什么区别?
// 不传参数,将不会按照数值大小排序,按照字符编码的顺序进行排序
let arr = [30,10,111,35,1899,50,45];
console.log(arr.sort()); // [10, 111, 1899, 30, 35, 45, 50]
console.log(arr.sort((a,b) => a - b)); // [10, 30, 35, 45, 50, 111, 1899]
  1. sort方法用的什么算法实现的?
sort() 方法用原地算法对数组的元素进行排序,并返回数组。在计算机科学中,就地算法是一种不使用辅助数据结构来转换输入的算法。
  1. 降序实现?
sort((a,b) => b - a)
  1. 会改变原始数组吗?
let arr = [5,2,8,7,3];
console.log(arr.sort((a, b) => a - b)) // [2, 3, 5, 7, 8]
console.log(arr) // [2, 3, 5, 7, 8]

参考文献:

  1. 图片来源:visualgo网站
  2. 《数据结构与算法javascript描述》

预留疑问:

  1. 请问诸位,如果用sort方法给汉字排序,它是按照什么来排序的?

后记:

以上就是面试过程中与实际项目中会遇到的一些排序类问题,在此做一个记录与总结,希望能帮助到有需要的小伙伴。我是一个前端小菜鸡,一直都在学习的路上,若是我有什么错误的地方还望各位能批评指正,在此非常感谢!