Java數據結構和算法(三)--三大排序--冒泡、選擇、插入排序

三大排序在咱們剛開始學習編程的時候就接觸過,也是剛開始工做筆試會遇到的,後續也會學習希爾、快速排序,這裏順便複習一下java

冒泡排序:

步驟:算法

  一、從首位開始,比較首位和右邊的索引編程

  二、若是當前位置比右邊的大,則交換位置數組

  三、當前位置的索引向右移動一位,必須兩兩比較數據結構

圖例:數據結構和算法

代碼實現:學習

public static int[] sort(int[] array) {
	for (int i = 1; i < array.length; i++) {  //外層循環,表明着須要通過多少輪比較
		boolean flag = true;
		for (int j = 0; j < array.length-i; j++) {  //內層循環,兩兩比較,用來移動索引的,直到找到最大值,注意這裏是array.length-i,固然-1也能夠,只不過效率會下降,並且不必
			if (array[j]>array[j+1]) {
				int temp = array[j];
				array[j] = array[j+1];
				array[j+1] = temp;
				flag = false;
			}
		}
		if (flag) {  //理論上,要通過N-1輪比較,可是若是在以前數據正好是有序的,直接break,減小了循環的次數,這就是flag的做用
			break;
		}
	}
	return array;
}

public static void display(int[] array) {
	for (int i = 0; i < array.length; i++) {
		System.out.print(array[i] + " ");
	}
}
public static void main(String[] args) {
	int[] array = new int[]{77, 99, 33, 44 ,55, 11, 9, 101, 2};
	System.out.print("排序前:");
	display(array);
	sort(array);
	System.out.print("\r\n排序後:");
	display(array);
}
輸出結果:
排序前:77 99 33 44 55 11 9 101 2 
排序後:2 9 11 33 44 55 77 99 101 

上面代碼中註釋已經很明顯了,並且冒泡排序很簡單的,稍微看一遍,應該均可以寫出來了spa

冒泡排序的效率:3d

第一輪,通過N-1次比較,第二輪是N-2次比較,理論上通過N-1輪:(N-1)+(N-2)+...+1=N*(N-1)/2,在N比較大的時候,能夠約等於N^2/2blog

而數據交換的次數:若是數據徹底是隨機的,交換個多是50%,那就是N^2/4

因爲常數不算在大O算法中,能夠忽略2和4,因此能夠認爲冒泡排序的時間複雜度O(N^2)

在任何狀況,雙層循環咱們均可以認爲時間複雜度O(N^2),由於外層爲N次,內層爲N或者幾分之N

選擇排序:

選擇排序在冒泡排序的基礎上進行了改進

步驟:

  一、找到最小值的索引

  二、若是最小值的索引不是首位,就交換

  三、最小值的索引右移一位,繼續比較

圖例:

代碼實現:

public static int[] sort(int[] array) {
	for (int i = 0; i < array.length-1; i++) {
		int min = i;  //min爲最小值的索引,默認爲0
		for (int j = i+1; j < array.length; j++) {  //這裏是j=i+1開始的,循環結束獲得最小值的索引
			if (array[min]>array[j]) {
				min = j;  
			}
		}
		if (min != i) {  //若是索引不是首位,就交換
			int temp = array[i];
			array[i] = array[min];
			array[min] = temp;
		}
	}
	return array;
}

public static void display(int[] array) {
	for (int i = 0; i < array.length; i++) {
		System.out.print(array[i] + " ");
	}
}
public static void main(String[] args) {
	int[] array = new int[]{77, 99, 33, 44 ,55, 11, 9, 101, 2};
	System.out.print("排序前:");
	display(array);
	sort(array);
	System.out.print("\r\n排序後:");
	display(array);
}
輸出結果:
排序前:77 99 33 44 55 11 9 101 2 
排序後:2 9 11 33 44 55 77 99 101 

選擇排序的效率:

  數據交換次數從O(N^2)變成了O(N),可是比較次數仍是O(N^2),可是相比冒泡排序效率確定更好的,由於交換次數少得多了

插入排序:

大多數狀況下,插入排序是這三種排序算法中效率最好的,通常狀況下,比冒泡排序快一倍,比選擇排序也要快一點,但實現方面也要更麻煩

步驟:

一、把數組分爲有序和無序兩部分,默認array[0]爲有序,其餘爲無序

二、每次把無序的一個元素插入到有序數組中

三、索引後移,知道全部的元素都變有序

圖例:

代碼實現:

public static int[] sort(int[] array) {
	int i, j;
	for (i = 1; i < array.length; i++) {  //循環比較的次數,默認從1開始
		int temp = array[i];  //先保存要插入的元素
		j = i;
		while (j > 0 && temp < array[j-1]) {  //要插入的元素小於以前的元素,循環直到temp找到要插入的位置
			array[j] = array[j-1];  //將以前的元素後移一位
			j--;  //索引前移一位
		}
		array[j] = temp;  //把temp插入到要插入的位置,也就是第一個大於temp的元素的後面
	}
	return array;
}

public static void display(int[] array) {
	for (int i = 0; i < array.length; i++) {
		System.out.print(array[i] + " ");
	}
}
public static void main(String[] args) {
	int[] array = new int[]{77, 99, 33, 44 ,55, 11, 9, 101, 2};
	System.out.print("排序前:");
	display(array);
	sort(array);
	System.out.print("\r\n排序後:");
	display(array);
}
輸出結果:
排序前:77 99 33 44 55 11 9 101 2 
排序後:2 9 11 33 44 55 77 99 101 

插入排序的特色:

比較次數:1+2+3+...+N-1=N*(N-1)/2

每一輪排序發現插入點以前,平均只有全體數據項的一半進行比較,因此是N*(N-1)/4

複製的次數和比較的次數幾乎相同。然而,複製和交換的效率是不一樣的,因此,插入算法比比冒泡排序快一倍,比選擇排序也要快一點

對於有序或基本有序的數據來講,插入排序的效率很好,由於while循環老是false,只是外層的循環而已,時間複雜度O(N)

若是是逆序數據,效率和冒泡排序差很少

 

內容參考:<Java數據結構和算法>

未完待續。。。

相關文章
相關標籤/搜索