递归实现快速排序及其改进

快速排序

概念:

快速排序是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

实现:

1、设置一个基准元素;
2、将要排序的数组分割成两部分,小于等于基准元素全部在左边,大于等于基准元素的全在右边。(即确定基准元素在排列好的数组的最终位置);
3、将分割出来的两部分分别进行快速排序,重复1、2步,直至分割出来的元素个数小于2。

示例:

对数组{8,4,3,7,1,5,6,2}进行快排

1、选择要排序的数组的第一个元素为基准元素,将基准元素的值保存起来(挖空部分代表此处的值已没有意义,不是此时的值为空)
int base = num[i];	

在这里插入图片描述

2、从右边开始逐一查找比基准元素base小的值,找到之后将这个值移到基准元素base的左边
while (base <= num[j] && i < j) {//从右边开始找,在基准数右边找到比它小的数时退出循环
					j--;		
				}
				num[i] = num[j];//将找到的比基准小的数移到基准数左边

在这里插入图片描述

3、随后再从左边开始逐一查找比基准元素base大的值,找到之后将这个值移到基准元素base的右边
while (base >= num[i] && i < j) { //从左边开始找,在基准数左边找到比它大的数时退出循环
					i++;
				}
				num[j] = num[i];//将找到的比基准大的数移到基准数右边

在这里插入图片描述

4、重复2、3步,直至i和j指向同一位置

在这里插入图片描述

在这里插入图片描述

5、在i和j指向同一位置后,将基准元素base填入该位置,第一次循环结束

在这里插入图片描述

将原数组分为两部分再对其递归的进行快速排序,得到最终结果。
	quickSort(num, left, i-1);
	quickSort(num, i+1, right);

左半边:

在这里插入图片描述
右半边:
在这里插入图片描述
最终执行结果:
在这里插入图片描述
完整代码:

package boke;

import java.util.Arrays;

public class QuickSort {
	public static int[] quickSort(int[] num , int left, int right) {
		if (left < right) {
			int i = left;//左指针
			int j = right;//右指针
			int base = num[i];	
			//将所有比基准数小的都移到它的左边,比它大的都移到它的右边
			while (i < j) { 
				while (base <= num[j] && i < j) {//从右边开始找,在基准数右边找到比它小的数时退出循环
					j--;		
				}
				num[i] = num[j];//将找到的比基准小的数移到基准数左边
				while (base >= num[i] && i < j) { //从左边开始找,在基准数左边找到比它大的数时退出循环
					i++;
				}
				num[j] = num[i];//将找到的比基准大的数移到基准数右边
			}
			num[i] = base;//最后当i和j指向同一位置时,循环结束,将基准数填入该位置
			quickSort(num, left, i-1);
			quickSort(num, i+1, right);
		}	
		return num;
	}
	public static void main(String[] args) {
		int num[ ]= {4,8,3,7,1,5,6,2};
		System.out.println("原数组为:\n"+Arrays.toString(num));
		quickSort(num, 0, num.length-1);
		System.out.println("快速排序后:\n"+Arrays.toString(num));
	}
}

改进

在这代码中,代码不够简洁,我们可以把确定基准元素下标的操作封装成一个方法,这样可以增加代码的可读性,使得代码更加简洁。

package boke;

import java.util.Arrays;

public class QuickSort2 {
	public static int partition(int[] num, int i, int j) {
		int base = num[i];
		//将所有比基准数小的都移到它的左边,比它大的都移到它的右边
		while (i < j) { 
			while (base <= num[j] && i < j) {//从右边开始找,在基准数右边找到比它小的数时退出循环
				j--;		
			}
			num[i] = num[j];//将找到的比基准小的数移到基准数左边
			while (base >= num[i] && i < j) { //从左边开始找,在基准数左边找到比它大的数时退出循环
				i++;
			}
			num[j] = num[i];//将找到的比基准大的数移到基准数右边
		}
		num[i] = base;//最后当i和j指向同一位置时,循环结束,将基准数填入该位置
		return i;
	}
	
	public static int[] quickSort(int[] num, int left, int right) {
		if(left < right) {
			int baseIndex = partition(num, left, right);
			quickSort(num, left, baseIndex-1);
			quickSort(num, baseIndex+1, right);
		}
		return num;
	}
	public static void main(String[] args) {
		int num[ ]= {4,8,3,7,1,5,6,2};
		System.out.println("原数组为:\n"+Arrays.toString(num));
		quickSort(num, 0, num.length-1);		
		System.out.println("快速排序后:\n"+Arrays.toString(num));
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值