JS6种常见的排序方法、冒泡排序、选择排序、插入排序、堆排序、归并排序...

排序方法多重多样,主要讲究的是排序算法时间复杂度和排序速度

  1、 冒泡排序: 比较两个相邻的项,如果第一个大于第二个则交换他们的位置,元素项向上移动至正确的顺序,就好像气泡往上冒一样

      function bubbleSort(arr) {
          let len = arr.length;
          for (let i = 0; i < len; i++) {
              for (let j = 0; j < len - 1 - i; j++) {
                  if (arr[j] > arr[j+1]) {        //相邻元素两两对比
                      [arr[j + 1], arr[j]] = [arr[j], arr[j + 1]];
                  }
              }
          }
          return arr;
      }

 2、快速排序

      1) 首先,在数组中选择一个中间项作为主元
      2) 创建两个指针,左边的指向数组第一个项,右边的指向最后一个项,移动左指针,直到找到一个比主元大的项,接着,移动右边的指针,直到找到一个比主元小的项,然后交换它们。重复这个过程,直到左侧的指针超过了右侧的指针。这个使比主元小的都在左侧,比主元大的都在右侧。这一步叫划分操作
     3) 接着,算法对划分后的小数组(较主元小的值组成的的小数组, 以及较主元大的值组成的小数组)重复之前的两个步骤,直到排序完成

      function quickSort(arr, left, right) {
          let len = arr.length;
          let partitionIndex;
          left = typeof left !== 'number' ? 0 : left;
          right = typeof right !== 'number' ? len - 1 : right;
          if (left < right) {
              partitionIndex = partition(arr, left, right);
              quickSort(arr, left, partitionIndex - 1);
              quickSort(arr, partitionIndex + 1, right);
          }
          return arr;
      }
    
      function partition(arr, left, right) {     //分区操作
          let pivot = left;                      //设定基准值(pivot)
          let index = pivot + 1;
          for (let i = index; i <= right; i++) {
              if (arr[i] < arr[pivot]) {
                  [arr[i], arr[index]] = [arr[index], arr[i]];
                  index++;
              }
          }
          [arr[pivot], arr[index - 1]] = [arr[index - 1], arr[pivot]];
          return index - 1;
      }

3、选择排序:大概思路是找到最小的放在第一位,找到第二小的放在第二位,以此类推 算法复杂度O(n^2)

     function selectionSort(arr) {
        let len = arr.length;
        let minIndex;
        for (let i = 0; i < len - 1; i++) {
          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;
      }

4、插入排序:每次排一个数组项,假设数组的第一项已经排序,接着,把第二项与第一项进行对比,第二项是该插入到第一项之前还是之后,第三项是该插入到第一项之前还是第一项之后还是第三项

     function insertionSort(arr) {
        let len = arr.length;
        let preIndex, current;
        for (let i = 1; i < len; i++) {
            preIndex = i - 1;
            current = arr[i];
            while (preIndex >= 0 && arr[preIndex] > current) {
              arr[preIndex + 1] = arr[preIndex];
              preIndex--;
            }
            arr[preIndex + 1] = current;
        }
        return arr;
      }

5、 归并排序:Mozilla Firefox 使用归并排序作为Array.prototype.sort的实现,而chrome使用快速排序的一个变体实现的,前面三种算法性能不好,但归并排序性能不错 算法复杂度O(nlog^n)
       归并排序是一种分治算法。本质上就是把一个原始数组切分成较小的数组,直到每个小数组只有一个位置,接着把小数组归并成较大的数组,在归并过程中也会完成排序,直到最后只有一个排序完毕的大数组

        function mergeSort(arr) {  //采用自上而下的递归方法
          let len = arr.length;
          if(len < 2) {
              return arr;
          }
          let middle = Math.floor(len / 2),
          left = arr.slice(0, middle),
          right = arr.slice(middle);
          return merge(mergeSort(left), mergeSort(right));
      }
    
      function merge(left, right){
          let result = [];
          while (left.length && right.length) {
              if (left[0] <= right[0]) {
                  result.push(left.shift());
              } else {
                  result.push(right.shift());
              }
          }
          result.push(...left);
          result.push(...right);
          return result;
      }

6、堆排序:堆排序把数组当中二叉树来排序而得名。

       1)索引0是树的根节点;

        2)除根节点为,任意节点N的父节点是N/2;

        3)节点L的左子节点是2*L;

        4)节点R的右子节点为2*R + 1
       本质上就是先构建二叉树,然后把根节点与最后一个进行交换,然后对剩下对元素进行二叉树构建,进行交换,直到剩下最后一个

      var len;    //因为声明的多个函数都需要数据长度,所以把len设置成为全局变量
      function buildMaxHeap(arr) {   //建立大顶堆
          len = arr.length;
          for (let i = Math.floor(len / 2); i >= 0; i--) {
              heapify(arr, i);
          }
      }
      function heapify(arr, i) {     //堆调整
          let left = 2 * i + 1;
          let right = 2 * i + 2;
          let largest = i;
          if (left < len && arr[left] > arr[largest]) {
              largest = left;
          }
          if (right < len && arr[right] > arr[largest]) {
              largest = right;
          }
          if (largest !== i) {
              [arr[i], arr[largest]] = [arr[largest], arr[i]];
              heapify(arr, largest);
          }
      }
      function heapSort(arr) {
          buildMaxHeap(arr);
          for (let i = arr.length - 1; i > 0; i--) {
              [arr[0],arr[i]]=[arr[i],arr[0]];
              len--;
              heapify(arr, 0);
          }
          return arr;
      }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liuwenjie_

感谢打赏,问题留言~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值