選擇排序、插入排序、希爾排序

選擇排序

工作原理是從待排序的數據元素中選出最小(或最大)的一個元素,並與第一個數交換位置,然後選擇剩下數組中最小的數,放到數組的第二個位置,
一次類推。
圖解過程如下:

選擇排序特點是:
1、運行時間和數組內容無關:我們會發現,即使是一個已經排序好的數組去使用選擇排序,運行的時間與隨機的數組排序時間居然一樣長
2、移動的數據少:數組的交換次數和數組大小是線性關係。

/**
 * 選擇排序 每次選擇剩下數組中最小的數,然後與剩下數組最前面的數交換位置,直到結束。
 * 
 * @author xiaoqi
 *
 */
public class Selection {

	public static void sort(int[] a) {
		for (int i = 0; i < a.length; i++) {
			int min = i;// min爲最小值的下標
			//找出剩餘數組的最小值
			for (int j = i + 1; j < a.length; j++) {
				if(a[min] > a[j]){
					min = j;
				}
			}
			//交換位置
			int temp = a[i];
			a[i] = a[min];
			a[min] = temp;
		}
	}

}


插入排序

插入排序就如同我們打牌一樣,按照順序把每張牌插入一個已經排好序的數組中,剩餘的數組右移即可。
圖解如下:
特點,插入排序所需時間與數組的初識順序相關,通過這點我們知道,它的運行效率是要高於選擇排序的。其比較適合部分有序和規模中小的數組。
/**
 * 插入排序 如同打牌一樣,將剩下數組的第一個插入到前面已經排好序的數組中,然後後移插入位置到原位置的數組一位 特別適合有一定順序的數組
 * 
 * @author xiaoqi
 *
 */
public class Insertion {

	/**
	 * 將a[i]取出,然後從a[i-1]的位置開始從已經排序好的數組的最後一個位置開始向左(依次到第0個位置)比較,大於就交換位置
	 * 
	 * 通過交換位置的方式向右移動
	 * @param a
	 */
	public static void sort2(int[] a) {
		for (int i = 1; i < a.length; i++) {
			for (int j = i; j > 0; j--) {
				if (a[j] < a[j-1]) {
					int temp = a[j-1];
					a[j-1] = a[j];
					a[j] = temp;
				}
			}
		}
	}
}


希爾排序

希爾排序是對插入排序的一種優化。我們知道,插入排序是適合部分有序的數組,這樣就可以使移動的數組儘量的小。而希爾排序就是先把一個數組變成“部分有序”,再進行插入排序,從而得到結果。他的思想是設置一個h,通過插入排序,讓數組中任意間隔h的元素都是有序的,然後縮小h的值,再排序,直到h爲1。因此它的效率取決於h的選取。
圖解:

/**
 * 希爾排序 是插入排序的一種改進,它的空間複雜度取決於一個常數因子,但是小於插入排序。
 * 思想:把數組分爲間隔爲h的h個數組,然後分別插入排序,再把分爲h/k(k>1)個數組,再插入排序,直到h爲1。
 * @author xiaoqi
 *
 */
public class Shell {
	public static void sort(int[] a){
		int N = a.length;
		int h = 1;
		//假設這個常數因子是 d = 1/3
		//先得到一個h/d + 1大於 數組長度的最小值
		while(h < N/3){
			h = 3 * h + 1;
		}
		//進行插入排序直到h爲1
		while(h >= 1){
			//每個數組間隔爲h,進行插入排序
			for(int i=h;i< N;i++){
				for(int j = i;j >= h;j -= h){
					if(a[j] < a[j-h]){
						int temp = a[j];
						a[j] = a[j-h];
						a[j-h] = temp;
					}
				}
			}
			//縮小h
			h = h /3;
		}
		SortTest.show();
		SortTest.isSorted(a);
	}
}




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