Java快速排序(二)

263 阅读1分钟

双路快速排序

上一种快速排序会导致有大量重复键值的退化为时间复杂度为O(n^2),如图

为此,我们可以将一般的快速排序改进为双路快速排序,如图。定义两个索引,从序列两边分别检索排序

双路快速排序法基本思想

arr[l, ..., r],选定v = arr[l] 作为标定点, arr[l, ..., i) <=v, i 索引所指元素与 v 比较,小于v, i 索引右移,即i++; arr(j, ..., r] >=v, j 索引所指元素与 v 比较,大于v, j 索引左移,即j--; 如果前面两个条件不满足了,则交换 arr[i] 与 arr[j] 的值,i++, j--,继续以上比较; 最后当 i > j 时,交换 arr[l] 与 arr[j]的位置,完成排序。

Java双路快速排序代码:

package lianxi;

public class QuickSort {

	private QuickSort() {
		
	}
	private static int   partition2(int[] arr,int l,int r) {
		
		int v=arr[l];
		int i=l+1;int j=r;
		while( true ) {
			while(i<=r && arr[i]<v) i++;
			while(j>=l+1&& arr[j]>v)j--;
			if (i>j) break;
			swap(arr,i,j);
			i++;
			j--;
		}
		swap(arr,l,j);
		return  j;
	}
	
	private static void swap(int[] arr,int i,int j) {
    	int t = arr[i];
	    arr[i]= arr[j];
	    arr[j]=t;
	}
	
	private static void  sort(int[] arr, int l,int r) {
		
		if(l>=r)
		return;
		int p =partition2(arr,l,r);
		
		sort(arr,l,p-1);
		sort(arr,p+1,r);
	}
	
	public static void sort(int[] arr) {
		int n=arr.length;
		sort(arr,0,n-1);
	}
	
	public static void main(String[] args) {
		int[] arr = {2,4,3,1};
		
		QuickSort.sort(arr);
		for(int i=0;i<arr.length;i++) {
			System.out.println(arr[i]);
		}
		
	}
}

总结

双路快速排序利用两个索引从两边开始检索,避免了重复键值多的时候导致两边不平衡的情况,它的实现也并不难。