JS实现常规的排序算法

144 阅读2分钟

1. 冒泡排序

  1. 特点:从第一个数开始,相邻元素两两对比,小的数放前面。(每循环一次,最后一个数都会被确定下来,为每轮的最大数)
  2. 图片演示:
  3. 代码实现
    const arr = [1, 6, 7, 11, 4, 2, 88, 22, 44];
    function bubbleSort(arr) {
      if (!Array.isArray(arr)) {
        return arr;
      }
      const len = arr.length;
      for (let i = 0; i < len - 1; i++) {
      	// 因为已经确定最后i个数为最大的数
        // 所以可以省略i个数
        for (let j = 0; j < len - 1 - i; j++) {
          // 找到前面比后面大的 交换
          if (arr[j] > arr[j + 1]) {
            let temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j] = temp;
          }
        }
      }
      return arr;
    }
    console.log(bubbleSort(arr));

2. 选择排序

  1. 特点:从第一个数开始,循环一圈找最小的数交换位置。(每循环一圈,第一个数都会被确定下来,为每轮最小的值)
  2. 图片演示:
    const arr = [1, 6, 7, 11, 4, 2, 88, 22, 44];
    function selectSort(arr) {
      if (!Array.isArray(arr)) {
        return arr;
      }

      const len = arr.length;

      for (let i = 0; i < len; i++) {
      	// 每一轮最小数字的index
        let minIdx = i;
        for (let j = i + 1; j < len; j++) {
          // 找到比minIdx更小的数字了 先记录索引,因为可能后面有更小的
          if (arr[minIdx] > arr[j]) {
            minIdx = j;
          }
        }
        // 交换
        let temp = arr[i];
        arr[i] = arr[minIdx];
        arr[minIdx] = temp;
      }
      return arr;
    }
    console.log(selectSort(arr));

3. 插入排序

  1. 特点:从第二个数开始,跟前一个数比较,若比前一个数小,则交换位置,接着跟前一个数比较,直到比前一个数大为止。(从第一张开始整理扑克牌,小的往前插)(可能会出现一个数从最后比较到最前面,比较费时)
  2. 图片演示:
  3. 实现
	const arr = [1, 6, 7, 11, 4, 2, 88, 22, 44];
	function insertSort(arr) {
      if (!Array.isArray(arr)) {
        return arr;
      }

      const len = arr.length;
      for (let i = 1; i < len; i++) {
        let temp = arr[i];
        let j = i - 1;
        // while (j >= 0 && arr[j] > temp) {
        //   arr[j + 1] = arr[j];
        //   j--;
        // }
        for (; j >= 0; j--) {
          if (arr[j] > temp) {
            arr[j + 1] = arr[j]
          } else {
            break;
          }
        }
        arr[j + 1] = temp;
      }
      return arr;
    }
    console.log(insertSort(arr));

4. 希尔排序

  1. 特点:
    • 希尔排序属于插入类排序,是将整个有序序列分割成若干个小的子序列分别进行插入排序。
    • 排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序,然后取d2<d1,重复上述分组和排序操作,直至d1=1,即所有记录放进一个组中排序为止。(将每间隔一定步距的数取出来进行比较,比如gap=5,就是把第1个、第6个、第11个...数取出来进行插入排序)
  2. 优点:
    • 当n值很大时,数据项每一趟排序需要移动的个数很少,但数据项的距离很长;当n值减小时,每一趟需要移动的数据增多,此时已经接近于它们排序后的最终位置。
    const arr = [1, 6, 7, 11, 4, 2, 88, 22, 44];
    function shellSort(arr, gap) {
      if (!Array.isArray(arr)) {
        return arr;
      }
      if (!gap) {
        gap = Math.floor(arr.length / 2);
      }

      const len = arr.length;

      while (1 <= gap) {
        for (let i = gap; i < len; i++) {
          let j = 0;
          let temp = arr[i];
          //
          for (j = i - gap; j >= 0; j -= gap) {
            if (arr[j] > temp) {
              arr[j + gap] = arr[j];
            } else {
              break;
            }
          }
          // for (j = i - gap; j >= 0 && temp < arr[j]; j -= gap) {
          //   arr[j + gap] = arr[j];
          // }
          arr[j + gap] = temp;
        }
        gap = Math.floor(gap / 2);
      }
      return arr;
    }
    console.log(shellSort(arr));

5.归并排序

  1. 特点:
    • 归并排序有两种实现方法:下面讲递归法:
    • 将原数组用二分法一直分到两个数为一组,然后通过比较将较小的数放到前面(通过一个中间数组排序);然后一层层向上排序。
    • (就是两个数比较进行排序,然后两组(四个数)进行比较排序,然后两组(八个数)进行比较排序…)
  2. 图片演示:
	const arr = [1, 6, 7, 11, 4, 2, 88, 22, 44];
    function mergeSort(arr) {
      // console.log(arr);
      if (arr.length === 1) {
        return arr
      }

      const mid = Math.floor(arr.length / 2);
      const left = arr.slice(0, mid);
      const right = arr.slice(mid, arr.length);

      return merge(mergeSort(left), mergeSort(right));
    }

    function merge(left, right) {
      // console.log(left, right);
      const leftLen = left.length;
      const rightLen = right.length;
      const ret = [];
      var i = 0;
      var j = 0;
      while (i < leftLen && j < rightLen) {
        if (left[i] < right[j]) {
          ret.push(left[i]);
          i++;
        } else {
          ret.push(right[j]);
          j++;
        }
      }
      while (i < leftLen) {
        ret.push(left[i])
        i++;
      }
      while (j < rightLen) {
        ret.push(right[j])
        j++;
      }
      // debugger;
      return ret;
    }
    console.log(mergeSort(arr))
  • 还有归并排序等其他后续补上哈~
  • 有什么更好的方法欢迎提出来~
  • 有错误也希望大家能提醒下~