快速排序的递归实现

快速排序(Quicksort),又称划分交换排序(partition-exchange sort),简称快排,是一种效率很高的排序算法。快速排序是不稳定的排序方法,当数组是完全无序时, 时间复杂度最低,为O(nlog2n) ,当数组完全有序时,时间复杂度最高,为O(n^2)。

排序思路:

·从数列中挑出一个元素,称为"基准"。
·重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。
	在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
·递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
·递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,
	它至少会把一个元素摆到它最后的位置去。


看以下程序:

import java.util.Arrays;

public class QuickSort {
	/** 找基准 */
	public static int partion(int[] arr, int start, int end) {
		
		int tmp = arr[start];
		
		while (start < end) {
			// 若结束索引对应数据大于开始索引对应数据,结束索引前移
			while (arr[end] >= tmp && start < end) {
				--end;
			}
			// 若开始索引和结束索引相遇,说明该数据已经有序
			if (start >= end) {
				break;
			}else {
			// 若结束索引对应的数据小于开始索引对应的值,将结束索引对应的数据赋值给开始索引
				arr[start] = arr[end];
			}
			// 若开始索引对应数据结束索引对应数据,开始索引后移
			while (arr[start] <= tmp && start < end) {
				++start;
			}
			// 若开始索引和结束索引相遇,说明该数据已经有序
			if (start >= end) {
				break;
			}else {
			// 若开始索引对应的数据大于结束索引对应的值,将开始索引对应的数据赋值给结束索引
				arr[end] = arr[start];
			}
		}
		
		arr[start] = tmp;
		// 返回基准对应的索引
		return start;
	}
	
	public static void quickTest(int[] arr, int start, int end) {
		
		int par = partion(arr, start, end);
		// 若基准左边至少还存在两个数据,对这边的数据再找一次索引
		if (par >= start + 1) {
			quickTest (arr, start, par - 1);
		}
		// 若基准右边至少还存在两个数据,对这边的数据再找一次索引
		if (par < end - 1) {
			quickTest (arr, par + 1, end);
		}
	}
	
	public static void main(String[] args) {
		int[] arr = {20, 23, 12 , 14, 45, 2, 89, 100, 65, 77, 96};
		quickTest(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(arr));
	}
}

以上程序的输出结果是:[2, 12, 14, 20, 23, 45, 65, 77, 89, 96, 100]


找基准的过程是这样的:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述



快排的优化方案:当数据个数较少时,用直接插入排序效率较高:

public static void quickSort(int[] arr, int start, int end) {
		if (end - start + 1 < 100) {
			insertSort(arr);
			return;
		}

		int par = partion(arr, start, end);
		
		if (par > start + 1) {
			quickSort (arr, start, par - 1);
		}
		
		if (par < end - 1) {
			quickSort (arr, par + 1, end);
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值