玩转经典排序算法

吐槽君 分类:javascript

排序算法是非常常见的面试题, 有了这个, 再也不怕啦

1. 冒泡排序

相邻元素两两比较 大的数字往后排序

    function bubble(arr) {
      let flag = false; // 提交结束冒泡的标识
      if (arr.length < 2) return arr;
      for (let i = 0; i < arr.length; i++) {
        flag = false; // 循环内的标识
        for (let j = 0; j < arr.length - 1 - i; j++) {
          // 从0开始, 到length-1-i结束
          if (arr[j] > arr[j + 1]) {
            const temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
            flag = true; // 表示进行了数据交换
          }
          if (!flag) break; // 如果没有进行数据交换, 表示已经排序完成, 跳出循环
        }
      }
      console.log("arr", arr);
      return arr;
    }
    // bubble([1, 4, 3, 4, 5, 6, 3, 2, 21, 2]);

 

2. 插入排序

拿到一个元素, 和前面的所有元素对比, 只要比他大就交换位置

    function insert(arr) {
      let len = arr.length;
      if (len < 2) {
        return arr;
      }
      let cur, pre;
      for (var i = 1; i < len; i++) {
        // 从1开始, len结束
        cur = arr[i];
        pre = i - 1;
        while (pre >= 0 && cur < arr[pre]) {
          arr[pre + 1] = arr[pre];
          pre--;
        }
        arr[pre + 1] = cur;
      }
      console.log("arr", arr);

      return arr;
    }
    // insert([1, 4, 3, 4, 5, 6, 3, 2, 21, 2]);
 

3.选择排序

最小的元素放在起始位置, 再从剩下的未排序的数组选最小值, 放在已经排序的后面

    function select(arr) {
      let len = arr.length;
      let minIndex, temp;
      for (let i = 0; i < arr.length - 1; i++) {
        minIndex = i; // 定义最小元素的索引
        for (let j = i + 1; j < arr.length; j++) {
          if (arr[minIndex] > arr[j]) {
            minIndex = j; // 找到剩余数组中的最小值的索引, 赋值给minIndex
          }
        }
        // 交换当前arr[i]和arr[minIndex]的位置
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
      }
      console.log(arr);
      return arr;
    }
    // select([1, 4, 3, 4, 5, 6, 3, 2, 21, 2]);
 

4. 归并排序

  • 分治算法 递归 先处理子问题 再合并
  • 先把数组分成两部分 递归进行排序
    function mergeSort(arr) {
   // 具体排序逻辑
   function merge(left, right) {
     const result = [];
     let i = 0, // 初始化i,j 的值
       j = 0;
     // 如果i,j都分别小于对应的数组长度, result的值为两个数组中对应的i,j的最小值
     while (i < left.length && j < right.length) {
       if (left[i] < right[j]) {
         result.push(left[i++]);
       } else {
         result.push(right[j++]);
       }
     }
     while (i < left.length) {
       result.push(left[i++]);
     }
     while (j < right.length) {
       result.push(right[j++]);
     }
     return result;
   }
   // 根据中间数, 分割数组成两部分
   function sort(arr) {
     if (arr.length === 1) return arr;
     const middle = Math.floor(arr.length / 2);
     const left = arr.slice(0, middle);
     const right = arr.slice(middle, arr.length);
     // merge 函数递归
     return merge(mergeSort(left), mergeSort(right));
   }

   return sort(arr);
 }

 

5. 快速排序

根据一个基数, 分别排序左右两边的数组, 最后连起来变成整个数组

    function quickSort(arr) {
    // 具体逻辑
    function quick(arr) {
      if (arr.length <= 1) return arr;
      const baseIndex = Math.floor(arr.length >> 1); // 找到基准点的索引
      const base = arr.splice(baseIndex, 1)[0]; // 找到基准点, arr去掉这个数
      const left = [],
        right = [];
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] > base) {
          right.push(arr[i]);
        } else {
          left.push(arr[i]);
        }
      }
      return quick(left).concat([base], quick(right)); // 递归去找, 直到arr.length<=1 退出循环
    }
    let result = quick(arr);
    return result;
  }
  let result = quickSort([1, 4, 3, 4, 5, 6, 3, 2, 21, 2]);
  console.log(result, "result");

 

6.堆排序

--- 未完待续

  • 本人今天写排序写的太累了, 但也属实有趣 , 后续会补充此排序, 并加多注释...嘿嘿嘿

回复

我来回复
  • 暂无回复内容