经典排序算法---快排

一、快速排序的描述

归并排序一样,快速排序也采用了分治策略。以下是对数组A[p…r]进行快排的三步分治过程:

 分解:
      将数组A[p...r]分解为两个非空的子数组A[p...q-1]和A[p+1...r], 使得A[q] 大于等于A[p...q-1]中的任意一个元素,A[q]小于
      等于A[q+1...r]中的任意一个元素。
 解决:
 	  通过递归调用快速排序,对子数组A[p...q-1]和A[p+1...r]进行排序。
 合并:
 	 用整个排序过程是基于原址排序的,因此不需要进行合并。

二、代码实现

递归实现(Javascript)

function QuickSort(A, p, r){
	if(p < r){
		q = partition(A, p, r);
		QuickSort(A, p, q-1);
		QuickSort(A, q+1, r); 
	}
}

function partition(A, p, r){
	let x = A[r];
	let i = p - 1;
	for(let j = p; j < r; j++){
		if(A[j] <= x){
			i++;
			//swap(A[i], A[j])
			[A[i], A[j]] = [A[j], A[i]];
		}
	}
	//swap(A[r], A[i]);
	[A[i], A[r]] = [A[i], A[r]];
	return i + 1;
}

非递归实现


function getRandom(a, b) {
	let r = Math.floor(Math.random() * (b - a)) + a;
	return r;
}
Array.prototype.quickSort = function(fn = (a, b)=>(a - b)){
	const A = this;
	const len = this.length;
	let p = 0,
		r = len - 1;
	
	// 使用一个数组来模拟递归栈
	const stack = [[p, r]];

	while(stack.length > 0){
		[p, r] = stack.pop();
		let i = p-1,
			j = p,
			x = A[r];
		
		// 随机选取比较的主元---随机化快排
		let t = getRandom(p, r+1);
		[A[t], A[r]] = [A[r], A[t]];
		x = A[r];
		
		// 进行一趟快速排序
		// [Ap,...,Ar] --> [Ap,...,Ai,...Ar], 任意i∈[p, r],    Ap < Ai < Ar
		while(j < r){
			if(fn(x, A[j]) >= 0){
				i++;
				
				// swap(A[i], A[j])
				[A[i], A[j]] = [A[j], A[i]];
			}
			j++;
		}
		i++;
		
		// 确定当前主元的位置
		// 这也是快排的性质之一,即每一趟快排确定一个元素的位置
		[A[i], A[r]] = [A[r], A[i]];
		
		// 保证子数组元素个数至少2个
		if(i-1 > p){
			stack.push([p, i-1]);
		}
		if(i+1 < r){
			stack.push([i+1, r]);
		}

	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值