快速排序(递归求解)

思想

在学习算法分析的时候,一开始接触的就是递归与分治策略。分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。可以递归地解决这些子问题,然后将子问题的解合并最终求得原问题。

这里的快速排序就运用了递归求解的思想

通过一趟扫描将待排序的元素分割成独立的三个部分:

  • part1:所有不大于基准元素的元素
  • part2:基准元素(pivot)
  • part3:所有不小于基准元素的元素

再按照此过程对第一个序列和第三个序列分别进行排序,直到所有元素按顺序排列。
注:此过程可以递归进行

过程

分解

在A[low:high]中选定一个元素作为基准元素(pivot),以此基准元素为标准将待排序列划分两个子序列
其中:A[low:pivotpos - 1]中的所有元素的值均小于等于A[pivotpos],序列A[pivotpos + 1:high]中的所有元素的值均大于等于A[pivotpos]。

关键:序列划分

-设待排序列为A[low, high],该划分过程以第一个元素作为基准元素

  1. 设置两个参数i = A[low]和j = A[high]
  2. 选取A[low]为基准元素,令pivot = A[low]
  3. 令 j 从 j 位置开始向左扫描,若A[j] >= pivot则 j 前移一个位置(j - -)。重复该过程,直到A[j] < pivot,此时将A[j] 与 A[i] 进行交换,i++。
  4. 令 i 从 i 位置开始向右扫描,如果 A[i] <= pivot则 i 向后一个位置(i++)重复该过程,直到找出A[i] > pivot,将A[j] 与 A[i]进行交换,j - -
  5. 重复3、4步骤,交替改变扫描方向,从两端向中间考虑直到 i = j
    此时 i 和 j 指向同一个位置,即基准元素pivot的最终位置

求解子问题

对A[low:pivotpos - 1]和A[pivotpos + 1:high]分别通过递归调用快速排序算法进行排序。

合并

将两个子序列合为一个完整的序列。

伪代码描述

QUICK-SORT(A, LOW, HIGH)
	IF low < high
		pivotpos = PARTITION(A, low, high) //划分序列
		QUICK-SORT(A, low, pivotpos-1) //对左区间递归排序
		QUICK-SORT(A, pivotpos+1, high) //对右区间递归排序
PARTITION(A, low, high, pivoIndex)
	i = low, j = high, pivot = A[pivotIndex]
	WHILE i < j
		WHILE i < j AND A[j] >= pivot 
			j--
		IF i < j 
			SWAP(A, i++, j)
		WHILE i < j AND A[i] <= pivot 
			i++
		IF i < j 
			SWAP(A, i , j--)

代码描述

package test;
public class QuickSortDC {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int a[] = {49, 38, 65, 97, 76, 13, 27};
		QuickSortDC.printArray(a);
		QuickSortDC.quickSort(a, 0, 6);
		QuickSortDC.printArray(a);

	}
	
	public static void quickSort(int[] aa, int low, int high) {
		if (low < high) {
			
			int pivotpos = QuickSortDC.partitionOnePass(aa, low, high, low); //划分序列
			QuickSortDC.quickSort(aa, low, pivotpos-1); //对左区间递归排序 
			QuickSortDC.quickSort(aa, pivotpos+1, high); //对右区间递归排序
		}
	}

	public static int partitionOnePass(int[] aaa, int low, int high, int pivotIndex) {
		int i = low, j = high, pivot = aaa[pivotIndex];
		
		while(i < j) {
			
			
			while((i < j) && (aaa[j] >= pivot))
			{
				j --;	
			}
				
			if(i < j)
			{
				QuickSortDC.swap(aaa, i++, j);	
			}
				
			while((i < j) && (aaa[i] <= pivot))
			{
				i ++;
			}
			if(i < j)
			{
				QuickSortDC.swap(aaa, i, j--);				
			}
		}
		
		return j;
	}
	
	public static void swap(int[] aaaa, int i, int j) {
		int iTemp = aaaa[i];
		aaaa[i] = aaaa[j];
		aaaa[j] = iTemp;
	}
	
	public static void printArray(int a5[]) {
		System.out.println();
		for(int i = 0; i < a5.length; i ++)
			System.out.print("\t" + a5[i]);
		System.out.println();
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值