排序算法--快速排序

一.快速排序的思想

快速排序可以认为是冒泡排序的升级版,它最重要的思想是分而治之
在这里插入图片描述
比如我们有如上这样一段数字需要排序:
第一步:随机选择一个数字,假设选择65
第二步:通过算法,将所有小于65的数字放在65的左侧,将大于65的数字放在65的右侧
第三步:递归的处理左边的数字(比如选择31来处理左侧),递归的处理右侧的数字(比如选择81来处理右侧的数字)
最终:排序完成

那么快速排序和冒泡排序的区别在哪里呢?
在快速排序中,选择的65可以一次性的放在最正确的位置,之后不需要任何移动,即快速排序对数字的定位是一次性的
而冒泡排序需要将数字两两比较,找到最大值,并不断向后移

二.快速排序的枢纽

比较优秀的解决方案就是:取头、中、尾的中位数,比如8,12,3的中位数就是8
快速排序的选择枢纽代码如下

//选择枢纽
ArrayList.prototype.median = function(left,right){
	// 1.取出中间的位置
	var center = Math.floor((left + right) / 2)
	// 2.判断大小,并且进行交换
	if(this.array[left] > this.array[right]){
		this.swap(left,right)
	}
	if(this.array[left] > this.array[center]){
		this.swap(left,center)
	}
	if(this.array[center] > this.array[right]){
		this.swap(center,right)
	}
	// 3.将center换到right-1的位置
	this.swap(center,right - 1)
	
	return this.array[right - 1]
}

三.快速排序的代码

ArrayList.prototype.quickSort = function(){
	this.quick(0, this.array.length - 1)
}
ArrayList.prototype.quick = function(left, right){
	// 1.结束条件
	if(left >= right) return
	// 2.获取枢纽
	var pivot = this.median(left, right)
	// 3.定义变量,用于记录当前找到的位置
	var i = left
	var j = right - 1
	// 4.开始进行交换
	while(true){
		while(this.array[++i] < pivot){}
		while(this.array[--j] > pivot){}
		if(i < j){
			this.swap(i, j)
		}else{
			break
		}
	}
	// 6.将枢纽放在正确的位置,i位置
	this.swap(i, right - 1)
	// 7.分而治之
	this.quick(left, i - 1)
	this.quick(i + 1, right)
}

四.快速排序的效率

快速排序的平均效率:为O(N*logN),它是目前排序中最好的

刷题期间发现,有一些大厂会让默写快排,这种使用Math.random()会更方便一下,借鉴大佬的代码

let quickSort = (arr) => {
  quick(arr, 0 , arr.length - 1)
}

let quick = (arr, left, right) => {
  let index
  if(left < right) {
    // 划分数组
    index = partition(arr, left, right)
    if(left < index - 1) {
      quick(arr, left, index - 1)
    }
    if(index < right) {
      quick(arr, index, right)
    }
  }
}

// 一次***
let partition = (arr, left, right) => {
  // 取中间项为基准
  var datum = arr[Math.floor(Math.random() * (right - left + 1)) + left],
      i = left,
      j = right
  // 开始调整
  while(i <= j) {
    
    // 左指针右移
    while(arr[i] < datum) {
      i++
    }
    
    // 右指针左移
    while(arr[j] > datum) {
      j--
    }
    
    // 交换
    if(i <= j) {
//       swap(arr, i, j)
      [arr[i],arr[j]] = [arr[j],arr[i]];
      i += 1
      j -= 1
    }
  }
  return i
}


// 测试
let arr = [1, 3, 2, 5, 4]
quickSort(arr)
console.log(arr) // [1, 2, 3, 4, 5]
// 第 2 个最大值
console.log(arr[arr.length - 2])  // 4



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值