快速排序(遞歸實現)

在這裏插入圖片描述 在這裏插入圖片描述在這裏插入圖片描述
1.哨兵位置爲最終位置
2.partition就是切分過程
3.選擇一個哨兵,將一組數劃分爲全比它小、全比它大的左右兩部分,再分別對這兩部分繼續如此左右劃分,直到元素個數爲1.整個劃分結束時,數組已排好序。
4.至於partition過程,參見上圖。
5.圖一的劃分方式,退出循環後i所指爲第一個大於等於vot的元素,j所指爲最後一個小於等於vot的元素。因此最後使a[j]與a[lb]交換即可讓哨兵歸至原位。

僞碼:

void quickSort(int a[],int p,int r){
	if(p<r){
		int q=partition(a,p,r);
		quickSort(a,p,q-1);
		quickSort(a,q+1,r);
	}
}

代碼:

import java.util.Scanner;

public class 快排遞歸 {
	static void swap(int a[],int i,int j) {
		int tmp = a[i];
		a[i]=a[j];
		a[j]=tmp;
	}
	static int partition(int a[],int lb,int ub) {
		//以下爲圖一劃分方式
		int i=lb,j=ub+1;
		int vot=a[i];
		while(true) {
			while(i<ub&&a[++i]<vot);
			while(a[--j]>vot);
			if(i<j) swap(a,i,j);
			else break;
		}
		a[lb]=a[j];
		a[j]=vot;
		return j;
		//以下爲圖二劃分方式
		/*int i=lb,j=ub;
		int vot=a[i];
		while(true) {//一旦j==i就終止循環。因爲左遊標左側、右遊標右側代表已處理妥當的元素。而左右遊標之所指,代表要互相比較的兩個元素。相遇時,遊標左右已妥,而遊標本身進行對比不會改變什麼。因此結束。
			while(j>i&&a[j]>=vot) j--;
			if(j>i) {//加這個條件是篩掉,如,基準元素左側全是比它小的。下同。
				a[i++]=a[j];
			}
			while(j>i&&a[i]<=vot) i++;
			if(j>i) {
				a[j--]=a[i];
			}
			if(!(j>i)) break;
		}
		a[i]=vot;
		return i;*/
	}
	static void quickSort(int a[],int lb,int ub) {
		int q=-1;
		if(ub>lb) {
			q=partition(a, lb, ub);
			quickSort(a, lb, q-1);
			quickSort(a, q+1, ub);
		}
		
	}
	public static void main(String args[]) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int a[]=new int[n];
		for(int i=0;i<n;i++) {
			a[i]=sc.nextInt();
		}
		quickSort(a, 0, n-1);
		for(int i=0;i<n;i++) {
			System.out.println(a[i]);
		}
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章