常见排序算法-JS实现

常见排序算法-JS

在这里插入图片描述
在这里插入图片描述

冒泡排序

特点

  • 两两比较
  • 比较:N^2 / 2约等于 时间复杂度O(N^2)
  • 交换:假设比较两次交换一次,N^2 / 4 约等于 时间复杂度O(N^2)

在这里插入图片描述
在这里插入图片描述

代码实现

//冒泡排序
        bubbleSort() {
          for (let i = this.array.length - 1; i >= 0; i--) {
            for (let j = 0; j < i; j++) {
              if (this.array[j] > this.array[j + 1]) {
                this.swap(j, j + 1)
              }
            }
          }
        }

选择排序

特点

每轮排序选出一个最小或最大的元素再一个个插入数组

  • 比较:N^2 / 2 时间复杂度O(N^2)
  • 交换:N-1 时间复杂度O(N)
  • 所以选择排序效率上是优于冒泡排序的

在这里插入图片描述

代码实现

 //选择排序
        selectionSort() {
          let min = 0
          for (let i = 0; i < this.array.length; i++) {
            min = i
            for (let j = i; j < this.array.length; j++) {
              if (this.array[min] > this.array[j]) {
                console.log(min + ' ' + j)
                min = j
              }
            }

            this.swap(min, i)
          }
        }

插入排序

特点

从未排序元素中挑出一个元素挨个跟局部有序的元素进行比较,找到对应位置插入即可

  • 比较次数 :平均 N(N-1)/4,最坏 N(N-1)/2* ,时间复杂度:O(N^2)
  • 交换次数: 平均N*(N-1)/4 ,最坏N*(N-1)/2,时间复杂度:O(N^2)
  • 因为插入排序的比较次数开销较小,所以其在简单排序中的效率最高

在这里插入图片描述

代码实现

//插入排序
        insertSort() {
          //未排序的元素挨个跟局部有序的元素比较

          for (let i = 1; i < this.array.length; i++) {
            //i是局部有序元素的长度,指向要插入的元素
            let j = i //j是当前有序元素的下标,最后需要指向temp应该插入的下标
            let temp = this.array[i]
            while (this.array[j - 1] > temp && j >= 0) {
              this.array[j] = this.array[j - 1]
              j--
            }
            this.array[j] = temp
          }
        }

希尔排序

特点

希尔排序基于插入排序,根据元素长度算出增量,以增量分组,对分组进行插入排序,再减少增量继续以上操作直到增量小于0(计算增量使用原稿的方式N/2)

  • 比较次数:最坏 O(N^2),平均O(N*logN)
  • 交换次数:最坏 O(N^2),平均O(N*logN)
  • 希尔排序属于高级排序比所有简单排序的效率都要高,某种情况下还要好于快速排序
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

代码实现

shellSort() {
          //get gap

          for (
            let gap = Math.floor(this.array.length / 2);
            gap >= 1;
            gap = Math.floor(gap / 2)
          ) {
            //以gap为分组,然后对分组进行插入排序
            for (let i = gap; i < this.array.length; i += gap) {
              //i is the index of head of group
              let j = i // j是正确位置
              let temp = this.array[i]
              while (j > gap - 1 && this.array[j - gap] > temp) {
                this.array[j] = this.array[j - gap]
                j -= gap
              }
              this.array[j] = temp
            }
          }
        }

快速排序

特点

快速排序是冒泡排序的升级版,使用递归实现算法

  • 1.选出一个中位数(pivot:间隔点)放到元素倒数第一的位置
  • 2.设置左L右R两个指针指向将要排序的元素的头和尾
  • 3.遍历L,R分别与pivot进行比较,L不断自增当L指向的元素大于pivot时暂停,R相反
  • 4.当L >= R 时停止遍历,这时L的位置就指向了pivot的正确位置,且后续都不会改变
  • 5.分而治之,分隔点两边继续上述步骤进行递归
  • 时间复杂度:O(nlogN)

在这里插入图片描述

代码实现

//快速排序
        quickSort() {
          this.quick(0, this.array.length - 1)
        }

        quick(left, right) {
          //当left,right相等,结束递归
          if (left >= right) {
            return
          } else if (right - left == 1) {
            //长度只有两个的元素时,直接判断交换,结束递归
            if (this.array[left] > this.array[right]) {
              this.swap(left, right)
            }
            return
          }

          //拿到分隔点
          let pivot = this.getPivot(left, right)
          console.log(this.array)
          let l = left 
          let r = right - 1
          
          //遍历元素找到pivot对应正确位置,使pivot左边的元素都小于pivot,右边相反
          while (true) {
            while (this.array[++l] < pivot) {}
            while (this.array[--r] > pivot) {}
            if (l < r) {
              console.log(this.array[l] + ',' + this.array[r])
              this.swap(l, r)
            } else {
              break
            }
          }
          //将pivot对应正确位置
          this.swap(l, right - 1)
		
		  //分而治之
          this.quick(left, l - 1)
          this.quick(l , right)
        }

		//拿到中位数,分隔点
        getPivot(left, right) {
          let center = Math.floor((left + right) / 2)
          //判断三个元素大小进行交换
          if (this.array[left] > this.array[center]) {
            this.swap(left, center)
          }
          if (this.array[center] > this.array[right]) {
            this.swap(center, right)
          }
          if (this.array[left] > this.array[right]) {
            this.swap(left, right)
          }
		  //将中位数放到倒数第二的位置
          this.swap(center, right - 1)
          //返回中位数
          return this.array[right - 1]
        }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值