快速上手快速排序

1.快速排序的原理
如何判断一个数的位置是正确?
	如果一个数左边的数都比他小,右边的数都比他大,那么这么数的位置一定是正确的。
	所以我们只需要让需要排序的数和其他数比较,把小于这个数的数放到左边,大于这个数的数放到
右边就可以了。
	那快速排序中是怎么实现的呢?
	假如现在有一个数组:
	  【3, 7, 4, 9, 5, 1, 6】
	1. 假如我们要排好的数 3,那么3右边的数必须是比他大的。
	2.用3和最右边的数6比较,6大于3,没问题。
    3.继续往左找,1小于3,所以我们要做的就是把1放到3的左边,如果在生
 活中把1放到到3左边的任何一个位置都可以,可是在数组中不同,3的左
 边等着你的是ArrayIndexOutOfBounds。
	4.快速排序选择的方法是交换,当然我们也可以把3 7 4 9 5 整体往后移动一位,如果再把1放到3以
前的位置,这样显然太浪费时间了,交换才是最快的。
	交换后我们的数组就变成:
	   【1, 7, 4, 9, 5, 3, 6】
	5. 现在3右边的数都比他大了,没比较过的就剩下3左边的除了1以外的数了,3左边的数必须是比3
小的。
    6. 7大于3,位置不对,交换
	交换后我们的数组就变成:
	   【1, 3, 4, 9, 5, 7, 6】
	7.从3的位置又往后比较,不符合条件的就交换,重复步骤直到所有的数都比较完,那么我们就给3排好位置了。
   在上面的例子中,我们都是用脑子记住需要排序的数,左边排到了哪里,右边排到了哪里,因
此需要三个变量来存储,代码实现如下:
		int[] arr = {3, 7, 4, 9, 5, 1, 6};
		//保存左边排到了哪里,左指针
		int start = 0;
		//保存右边排到了哪里,右指针
		int end = arr.length-1;
		//保存需要排的数,基准值
		int key = arr[0];
		//左右走到一起了,说明每一个数都比较过了,位置不正确的也交换了,结束循环
		while(end>start) {
			//从后往前比较,右边的数如果比基准值大说明其位置正确
			while(end>start&&arr[end]>=key) {
				//右指针往左挪
				end--;
			}
				//减小右索引的时候 ,一种极端情况是右边的数都比基准值大,那么左右指针的值相等了
				//要不就是右索引位置的值小于这个基准值了,那它得放在左边,所以要交换
				if(arr[end] < key) {
					//一个数被同一个数异或俩次,值不变
					arr[end] = arr[end] ^ arr[start];
					arr[start] = arr[end] ^ arr[start];
					arr[end] = arr[end] ^ arr[start];
				}
				//因为直接交换是具有跳跃性的,也就是跳跃了俩个索引中间的值
				//交换之后及右索引往右的都比较过了,基准数到了未比较的最右边, 左边理论上要比基准小
				//所以大的数就要进行交换
				while(end>start && arr[start] <= key) {
					start++;
				}
					if(arr[start]  < key) {
						arr[end] = arr[end] ^ arr[start];
						arr[start] = arr[end] ^ arr[start];
						arr[end] = arr[end] ^ arr[start]; 
					}
	上面的代码只实现了一个排好一个数,如果需要排好所有数,我们需要用到递归。代码如下:
	public static void quickSort(int[] arr,int low,int high) {
		int start = low;
		int end = high;
		int key = arr[low];
		
		while(end>start) {
			while(end>start&&arr[end]>=key) 
				end--;
				
				if(arr[end] < key ) {
					arr[end] = arr[end] ^ arr[start];
					arr[start] = arr[end] ^ arr[start];
					arr[end] = arr[end] ^ arr[start];
				}
				
				while(end>start && arr[start] <= key) 
					start++;
					
					if(arr[start] > key) {
						arr[end] = arr[end] ^ arr[start];
						arr[start] = arr[end] ^ arr[start];
						arr[end] = arr[end] ^ arr[start];
					}
		}
		//基准值左边
		if(start > low) {
			quickSort(arr,low,start-1);
		}
		//基准值右边
		if(end < high) {
			quickSort(arr,end+1,high);
		}
	}
	本人第一次写博客,有点地方太过啰嗦,主要是记录一下自己的学习,也希望能帮到需要帮助像我一样的新手,不到之处,还请谅解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值