快速排序个人理解与java实现

    快速排序(Quick Sort)算法和冒泡排序算法类似,都是基于交换排序思想的。快速排序算法对冒泡排序算法进行了改进,从而具有了更高的执行效率。

    快速排序算法通过多次比较和交换来实现排序,排序流程如下:

    1. 从待排序的数组中选一个基准值(通常取数组中间位置的值或者第一个值),通过该基准值将数组分成左右两部分。其中大于等于基准值的数据在右部分,小于等于基准值的数据为左部分。

    2. 左右两部分的数据右可以独立选取基准值并排序,参照1,通过递归排好左侧数据,然后再递归排好右侧数据。

    一句话理解快速排序,取数组中间位置的值作为基准,将输入集分为两半,左右部分不断递归,排序完成。

以一组实验数据来加深理解:

每一行带颜色的部分为分区结果,红色代表左半部分(为左侧递归的输入,并且下一行的基准为该部分中间位置的值),绿色代表右半部分(为左侧递归的输入,并且下一行的基准为该部分中间位置的值)

排序前的数组为:           122   141   164   149   198   166   178   106   

以149第一次分区:        122   141   106   149   198   166   178   164   ,基准149为上一行数据中间位置的值

对左区(122   141   106   149 )进行递归

以141为基准左侧递归: 122   106   141   149   198   166   178   164   ,基准141为上一行左区数据中间位置的值
以122为基准左侧递归: 106   122   141   149   198   166   178   164   ,基准122为上一行左区数据中间位置的值

以141为基准右侧递归:106   122   141   149   198   166   178   164   ,基准141为上一行右区数据中间位置的值

左部分排列完成

对右区(198   166   178   164 )进行递归

以166为基准右侧递归:106   122   141   149   164   166   178   198   
以164为基准左侧递归:106   122   141   149   164   166   178   198   

以178为基准右侧递归:106   122   141   149   164   166   178  198   

右部分排列完成

排序后的数组为:           106   122   141   149   164   166   178   198   


下面为自己写快速排序算法

详细实现见以下注解,如需完整代码,请直接跳过这一段

<pre name="code" class="java">void quickSort(int[] arr, int left, int right) // 快速排序算法
{
	int f, t;
	int rtemp, ltemp;
	ltemp = left;
	rtemp = right;
//	f = arr[(left + right) / 2]; // 分界值
	f =arr[left];
//	f=arr[right];
	//不能使用最右侧数作为基准,因为左指针等于右指针时(下面的if语句中),默认当前值小于等于基准时,左指针++;
	//只需改为当前值大于等于基准时,右指针--;此语句就可以,同理此时f不能等于最左侧
	while (ltemp < rtemp) {
		while (arr[ltemp] < f) { //不能取等号,当基准左边都小于等于基准时,ltemp会越过基准的索引
			++ltemp;
		}
		while (arr[rtemp] > f) {
			--rtemp;
		}
            //此时如果ltemp==rtemp并且当前值小于等于基准值,执行下一个if,让ltemp指针后移(当然也可以让rtemp前移,此时不能用a[left]作为基准)
		if (ltemp<rtemp) {        //去掉if的话偶尔会排序出错,比如138 181 150 119 118 123 113 124 166 116 167 117 141 163 130 167 191 108 
			t = arr[ltemp];
			arr[ltemp] = arr[rtemp];
			arr[rtemp] = t;
			--rtemp;
			++ltemp;
		}
	}
            //下一个if保证ltemp为rtemp+1
            //ltemp左侧的数据小于等于基准,rtemp右侧大于等于基准,
	if (ltemp == rtemp) {        
		if (arr[ltemp] <= f)
			ltemp++;
		else
			rtemp--;
	}
            //左右分区结束,进入递归
	if (left < rtemp) {
		quickSort(arr, left, ltemp - 1); // 递归调用,实现左部分排序,ltemp左侧必定是小于等于分解值,rtemp减小到left,递归结束
                    //
	}
	if (ltemp < right) {
		quickSort(arr, rtemp + 1, right); // 递归调用,实现右部分排序,rtemp右侧必定是大于等于分解值,ltemp增大到right,递归结束
	}
}

 
完整java代码: 

public class test {
	static final int SIZE = 18;
	static void quickSort(int[] arr, int left, int right) // 快速排序算法
	{
		int f, t;
		int rtemp, ltemp;
		ltemp = left;
		rtemp = right;
//		f = arr[(left + right) / 2]; // 分界值
		f =arr[left];
//		f=arr[right];
		while (ltemp < rtemp) {
			while (arr[ltemp] < f) {
				++ltemp;
			}
			while (arr[rtemp] > f) {
				--rtemp;
			}       
			if (ltemp<rtemp) {
				t = arr[ltemp];
				arr[ltemp] = arr[rtemp];
				arr[rtemp] = t;
				--rtemp;
				++ltemp;
			}
		}
		if (ltemp == rtemp) {        
			if (arr[ltemp] <= f)
				ltemp++;
			else
				rtemp--;
		}
		if (left < rtemp) {
			quickSort(arr, left, ltemp - 1); // 递归调用
		}
		if (ltemp < right) {
			quickSort(arr, rtemp + 1, right); // 递归调用
		}
	}

	public static void main(String[] args) {
		int[] shuzu = new int[SIZE];
		int i;
		for (i = 0; i < SIZE; i++) {
			shuzu[i] = (int) (100 + Math.random() * (100 + 1)); // 初始化数组
		}
		
		System.out.print("排序前的数组为:\n"); // 输出排序前的数组
		for (i = 0; i < SIZE; i++) {
			System.out.print(shuzu[i] + " ");
		}
		System.out.print("\n");

		quickSort(shuzu, 0, SIZE - 1); // 排序操作

		System.out.print("排序后的数组为:\n");
		for (i = 0; i < SIZE; i++) {
			System.out.print(shuzu[i] + " "); // 输出排序后的数组
		}
		System.out.print("\n");

	}

}
 欢迎指出不足或者给点建议。 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值