排序之快速排序2

一.快速排序最壞狀況分析java

    上文章分析到快速排序-----排序之快速排序 。最後提到了一個思考題,什麼樣的狀況下快速排序是最壞狀況?算法

    有兩種狀況:數組

  1.   數組已經排好序(升序或者逆序)優化

        這種狀況,挑選了第一個元素爲主元,那麼主元就是數組中最大的或者是最小的,n劃分紅1和n-1ui

       時間複雜度T(n)=T(n-1)+T(1)+θ(n)  根據遞歸公式求得T(n)=O(n^2),和插入排序同樣。spa

  2.   數組全部元素都是重複的.net

        這種狀況和第一種狀況同樣,也是劃分紅1和n-1,時間複雜度T(n)=O(n^2)code

二.快速排序優化orm

     那麼該如何優化才能讓快排時間複雜度不超過O(nlgn)呢?blog

    (1) 針對第一種狀況,有兩種方法:① 隨機挑選主元;②打亂數組的順序。咱們以前的算法是挑選第一個元素爲主元,若是是隨機挑選,就避免了最壞狀況的第一種。或者在數組劃分前,先打亂數組的順序,也能夠達到一樣效果

   (2)第二種狀況,若是數組有大量的重複元素,那麼快速排序效率會大大下降,劃分的效果不理想,爲何?能夠本身想一下,怎麼解決呢?能夠用三向切分快速排序

三向切分快速排序示意圖:

   

  就是把數組分爲三份,小於主元,等於主元,大於主元 三份。

如:把{1,5,7,5,9,3,8,6,4,5}====>{1,3,4,5,5,5,7,9,8},這樣的話,等於主元的那一份就不用作遞歸,若是有大量重複的元素這種算法就比原始快排效率高不少,若是所有元素都是重複的,三向切分快速的時間複雜度爲O(n)。

三.三向切分快速算法過程

     如何才能把數組三等份,下面咱們經過例子來描述算法  a(n)={1,5,7,5,9,3,8,6,4,5}

                   1   5   7   5    9    3   8   6   4  5 

                    lt   i                                      gt 

  • 設v =a[0]  比較v和a[i] 

  • a[i]<v,交換a[lt]和a[i],lt和i都加1

  • a[i]>v 交換a[gt]和a[i],gt減1

  • a[i]=v  i加1 

  • 循環一直到i>gt,算法結束。

四.三向切分快速算法代碼實現   

/**
 * 快速排序
 * */
public class Quicksort {

	public Quicksort() {
		// TODO Auto-generated constructor stub
	}

	// 3向切分快速排序
	public static void sort3way(int[] arry, int low, int hight) {
		if (hight < low)
			return;
		int lt = low, i = low + 1, gt = hight;
		int pivot = arry[low];
		int temp = 0;
		while (i <= gt) {
			if (arry[i] < pivot) {
				// 交換arry[i]和a[lt]
				temp = arry[lt];
				arry[lt] = arry[i];
				arry[i] = temp;
				lt++;
				i++;
			} else if (arry[i] > pivot) {
				// 交換arry[i]和a[gt]
				temp = arry[gt];
				arry[gt] = arry[i];
				arry[i] = temp;
				gt--;
			} else {
				i++;
			}

		}
		sort3way(arry, low, lt - 1);
		sort3way(arry, gt + 1, hight);
	}

	public static void main(String[] args) {
		int[] arry = { 1, 5, 7, 5, 9, 3, 8, 6, 4, 5 };
		sort3way(arry, 0, arry.length - 1);
		for (int n : arry) {
			System.out.println(n);
		}
	}
}
相關文章
相關標籤/搜索