面試三 : 快速排序

    今天咱們看看快速排序,其實咱們是在大二上學期上的數據結構,如今基本上忘的差很少了,最近這兩年一直在作應用,因此這個面試官給我敲響了警鐘,雖說我面試的結果不怎麼樣,可是個人收穫仍是不少的,在這裏與你們分享一下。但願你們在面試以前,必定要看看咱們經常使用的算法,這是常常考的,還有就是面試官會問你算法複雜度,這是個很頭疼的問題,一開始學的時候就不會,但願哪一個大神有好的算算法複雜度的方法,請指教。
java

    下面咱們看看快速排序的思想 和 java實現
面試

    快速排序是對冒泡排序的一種改進。
算法

    不穩定,時間複雜度 最理想 O(nlogn)最差時間O(n^2)數組

    基本思想 : 利用的是 分治法的基本思想數據結構

    經過一躺排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一不部分的全部數據都要小,而後再按次方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。ide

    咱們看一下快速排序的步驟:
ui

    一趟快速排序的算法是:spa

    1) 設置兩個變量 i 和 j  排序開始的時候, i = 0   j = N -1   (N 爲數組的長度3d

    2)選取基準元素,一般選取數組的第一個元素爲基準元素 key = arr[0]blog

    3)  從 j 開始向前搜索,即由後向前(j--)搜索  ,找到第一個小於key的值 arr[j] 將arr[i] 和 arr[j]進行交換 而後中止

    4) 從 i 開始向後搜索,即由前向後(i++)搜索, 找到第一個大於key的值 arr[i]  將arr[i] 和 arr[j] 進行交換 而後中止

    5) 重複第 3 、四、 5步 直到 i == j 中止

    這樣第一趟排序就完成了,這樣就保證了 基準元素左面的元素都比基準元素小 ,基準元素右面的元素都比基準元素大 ,下面進行的就是在分別對基準元素左邊的(元素都比基準小)數組進行排序(和第一趟排序步驟同樣)和右邊的數組進行排序。(遞歸)

    wKiom1QjdRKSUtUDAAH1Jl6kT3k882.jpg

        java 算法實現:

        

package cn.edu.ytu.botao.java.sort;
/**
 * 
 * @author botao
 *
 */
public class Quicksort {
	
	public static void main(String[] args) {
		//須要排序的數組 arr 並初始化數組
		int[] arr = {49,38,65,97,76,13,27};
		Quicksort quicksort = new Quicksort();
		quicksort.sort(arr, 0, arr.length-1);
		quicksort.print(arr);
	}
	/**
	 * 將數組元素輸出
	 * @param arr
	 */
	public void print(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length-1) {
				System.out.print(arr[i]);
			}else {
				System.out.print(arr[i] + ",");
			}
		}
	}
	/**
	 * 
	 * @param arr 要排序的數組
	 * @param low 開始的下標
	 * @param high 結束的下標
	 */
	public void sort(int[] arr ,int low, int high) {
		//令 i = 開始的下標 令 j = 結束的下標
		int i = low;
		int j = high;
		
		//遞歸的終止條件
		if (i > j) {
			return ;
		}
		
		/**
		 * 注意: 遞歸終止的條件必定要在選取基準元素以前 不然會出現下標越界
		 */
		
		//基準元素 通常爲數組的第一個元素
		int key = arr[low];
		
		/**
		 * 第一趟排序開始
		 */
		//進行第一趟排序
		while (true) {
			//從後面往前走 j--
			while (j > i) {
				//基準元素 大於 後面的元素 因此要將前面的元素和後面的元素進行交換
				if (arr[j] < key) {
					int temp = arr[j];
					arr[j] = arr[i];
					arr[i] = temp;
					break;  //完成一次循環 退出
				}else {
					j--; 
				}
			}
			//從前面日後走 
			while (j > i) {
				//基準元素 小於 前面的元素 因此要將後面的元素與前面的元素進行交換 
				if (arr[i] > key) {
					int temp = arr[j];
					arr[j] = arr[i];
					arr[i] = temp;
					break;  //完成一次循環 退出
				}else {
					i++;
				}
			}
			//完成一趟循環 退出
			if (j == i) {
				break;
			}
		}
		/**
		 * 第一趟排序結束
		 */
		
		//完成第一趟循環後進行重複性遞歸
		//分而治之的左面的數組
		sort(arr, low, i-1);
		//分而治之的右面的數組
		sort(arr, i+1, high);
		//遞歸要加終止條件  在上面
	}

}
相關文章
相關標籤/搜索