JS手写函数面试

141 阅读2分钟

排序算法

冒泡排序

冒泡排序就是从序列中的第一个元素开始,依次对相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足就交换两个元素的位置。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作

时间复杂度:O(N²)。【因为有2个循环】

空间复杂度:O(1)。

 function bubbleSort(array) {
    const len = array.length;
    let i = 0;
    // 每轮循环都是从第一个元素开始, 循环len 次
    while (i < len) {
      // 每一次循环,结尾多一个排好序的元素,每次结尾都少遍历一个
      const lastIndex = len - 1 - i;
      i++;
      for (let j = 0; j < lastIndex; j++) {
        // 当前元素与下一个元素做比较,如果大于的话调换顺序
        if (array[j] > array[j + 1]) {
          [array[j], array[j + 1]] = [array[j + 1], array[j]];
        }
      }
    }
    return array;
  }

选择排序

在数组中先找出最小数的索引(最初假设第一个元素为最小值),设一个变量保存下来,把最小的元素放在数组最前面,重复前面的步骤,将最小值放在前一个最小值后面

时间复杂度:O(N²)。

空间复杂度:O(1)。

function selectSort(arr) {
    let len = arr.length;
    for(let i = 0; i < len; i++) {
        let minIndex = i;
        for(let j = i + 1; j < len; j++) {
            if(arr[j] < arr[minIndex]) minIndex = j;
        }
        [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]
    }
    return arr
}

插入排序

将第一个元素认为是一个有序数列,剩下的为无序数列,从第二个元素开始遍历,取无序数列中第一个元素跟有序数列元素比较(从最后面元素开始),若比有序数列小,有序数列元素往后挪移一位,直到比有序数列元素大,此时有序数列空一个位置,将当前值插入有序数列

时间复杂度:O(N²)。

空间复杂度:O(1)。

function insertionSort(array) {
    const len = array.length;
    // 从第二个开始遍历
    for (let i = 1; i < len; i++) {
      // 获取当前值
      const curValue = array[i];
      let j = i - 1;
      // 遍历 i 之前的元素,如果大于curValue,则直接往后挪一位
      while (j >= 0 && array[j] > curValue) {
        array[j + 1] = array[j];
        j--;
      }
      // 插入 curValue
      array[j + 1] = curValue;
    }
    return array;
  }

快速排序

方式一:

取一个基准数,剩下元素逐个跟其比较,小的放一个数组,大的放另一个数组,再对两个数组做同样操作直至排序完成,拼接基准数和两个数组。

劣:该种方式内存消耗多

function quickSort( arr ) {
    if(arr.length <= 1) return arr;
    const num = arr[0];
    let left = [], right = [];
    for(let i = 1;i < arr.length; i++) {
        if(arr[i]<=num) left.push(arr[i]);
        else right.push(arr[i]);
    }
    console.log(left, right)
    return quickSort(left).concat([num],quickSort(right));
}


var arr = [2,4,6,1,0,9,8]
quickSort(arr)

方式二:

function quickSort(arr, start, end) {
    function swap(arr, i, k) {
        let temp = arr[i];
        arr[i] = arr[k];
        arr[k] = temp;
    }
    // 数组分区,左小右大
    function partition(arr, left, right) {
        let storeIndex = left;
        let pivot = arr[right]; // 直接选最右边的元素为基准元素
        for(let i = left; i < right; i++) {
            if(arr[i] < pivot) {
                swap(arr, storeIndex, i); //将比基准元素大的跟比基准元素小的换位置
                storeIndex++; // 交换位置后,storeIndex 自增 1,代表下一个可能要交换的位置
            } 
        }
        swap(arr, storeIndex, right); // 将基准元素放置到最后的正确位置上
        return storeIndex;
    }
    function sort(arr, left, right) {
        if(left > right) {
            return;
        }
        let storeIndex = partition(arr, left, right);
        sort(arr, left, storeIndex - 1);
        sort(arr, storeIndex + 1, right);
    }
    sort(arr, start, end);
    return arr;
}
quickSort([3,7,8,5,2,1,9,5,4], 3, 7) // 只对部分元素排序