快速排序过程——递归与非递归解法

看了网上很多人的快排,有些核心没讲到,导致我走了弯路。

遍历每一个基准数A的第一次替换绝对是替换A的位置

比A大的甩到右边,比A小的甩到左边

这话怎么理解呢,如果基准数位置的值没被填充,可能会导致数据丢失,在取完前四个基准数时会就会明白了

黄色填充框是待替换区

简单来说,快排是为每一个基准数据找其正确索引位置的过程

给出序列:3 ,44,38,5,47,15,36,26

基准数据从哪里开始其实没区别,反正要执行n-1次,那就将原数组a拷贝到数组b,遍历b数组,然后分别从数组的两端扫描数组,设两个指示标志:low指向起始位置,high指向末尾

第一遍:temp = 3;

接下去

无论从low指针开始还是high指针开始都行,

low指针从头开始遍历指向的元素arr[low],当arr[low]>temp时,low++;其他情况时停下。

high指针从尾开始遍历指向的元素arr[high],当arr[high]<temp时,high--;其他情况时停下。

当low == high时,就是基数的索引位置,用temp值替换

所以low == high == 0,3不动

 第二遍:temp = 44;

 

low指针从头开始遍历指向的元素arr[low],当arr[low]>temp时,low++;其他情况时停下。

high指针从尾开始遍历指向的元素arr[high],当arr[high]<temp时,high--;其他情况时停下。

判断是low位置元素替换high元素,还是反之,除第一次外,后面遍历的指针 元素替换 另一指针元素,替换完的low(high)指针向后移,high(low)不动,待替换。

 俩个指针第一次停下,如图,面临是low指针元素替换high指针元素,还是反之。

第一次先看是low指针到基准数索引位置,还是high指针到基准数索引位置

基准数索引位置的值将被替换为26,替换完的low指针向后移动。high指针待替换

网上的某些文章永远是后面遍历的指针 元素替换 另一指针元素,替换完的low(high)指针向后移,high(low)不动,待替换。

原索引位置的值已经转存到temp,如果第一遍不填充该位置会造成数据丢失,第四个基准数就会明白

 俩个指针第二次停下,遵循后面遍历的指针 元素替换 另一指针元素,替换完的low(high)指针向后移,high(low)不动,待替换。所以47替换26,high向前移,low不动待替换。

指针第三次停下,遵循。。所以36替换47,low向后移,high不动待替换。

(省略一万字)

 第二遍结果

代码如下(java)

1.递归

public class QuickSort {
	public static void QuickSort(int[] arr, int low, int high) {
		if (low < high) {
			int index = getIndex(arr,low,high);
			QuickSort(arr,0,index - 1);
			QuickSort(arr,index + 1,high);
		}
	}

	public static int getIndex(int[] arr,int low,int high) {
		int tmp = arr[low];
		while (low < high) {
			while (low < high && tmp <= arr[high]) {
				high--;
			}
			arr[low] = arr[high];//第一次替换基准数的原索引位置
			while (low < high && tmp >= arr[low]) {
				low++;
			}
			arr[high] = arr[low];
		}
		arr[low] = tmp;
		printArray(arr);
		return low;
	}

	public static void printArray(int[] arr) {
		for (int a : arr) {
			System.out.print(a + " ");
		}
		System.out.println();
	}
	public static void main(String a[]) {
		int[] array= new int[]{3,44,38,5,47,15,36,26};
//		int[] array= new int[]{3,5,44,38,5,47,15,36,5,26};
		QuickSort(array,0,array.length - 1);
	}
}

2.非递归

public class QuickSort {
	public static int[] QuickSort(int[] arr) {
		int len = arr.length;
		int[] tArr = arr.clone();
		for (int i = 0; i < len - 1; i++) {//循环n-1次,0 or 1
			int lowIdx = 0,highIdx = len - 1,temp;
			temp = tArr[i];
			boolean flag = true;//true为high,false为low
			while(lowIdx != highIdx) {//low与high不相等
			    while(temp < arr[highIdx] && highIdx > lowIdx) {
					highIdx--;
					flag = true;
				}
				while(temp > arr[lowIdx] && highIdx > lowIdx) {
					lowIdx++;
					flag = false;
				}
				if (lowIdx != highIdx) {
					if (lowIdx != i && highIdx != i) {//非第一次
						if (flag) {
							arr[lowIdx] = arr[highIdx];
							lowIdx++;
							flag = false;
						} else {
							arr[highIdx] = arr[lowIdx];
							highIdx--;
							flag = true;
						}
					}
					if (lowIdx == i) {//第一次
						arr[lowIdx] = arr[highIdx];
						lowIdx++;
					}
					if (highIdx == i) {
						arr[highIdx] = arr[lowIdx];
						highIdx--;
					}
				}
			}
			arr[lowIdx] = temp;
			printArray(arr);
		}
		return arr;
	}

	public static void printArray(int[] arr) {
		for (int a : arr) {
			System.out.print(a + " ");
		}
		System.out.println();
	}

	public static void main(String[] a) {
		int[] array= new int[]{3,44,38,5,47,15,36,26};
//		int[] array= new int[]{3,5,44,38,5,47,15,36,5,26};
		QuickSort(array);
	}
}

 代码有点粗糙,但确实可行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值