java筆試攻略——base系列(十大排序算法 持續更新ing)

十大排序算法解析

排序:對某一序列對象根據某關鍵字進行排序
穩定性:排序前a在b前面,而a=b,排序後a還在b前面
內排序:所有排序在內存中完成
外排序:由於數據太大,因此將數據放到硬盤中,而排序通過磁盤和內存的數據傳輸才能進行

排序算法	  平均時間複雜度	   最好情況     最壞情況     空間複雜度	     排序方式     穩定性
冒泡排序	   O(n^2)	      O(n)           O(n^2)          O(1)	      In-place    穩定
選擇排序	   O(n^2)         O(n^2)         O(n^2)          O(1)        In-place	  不穩定
插入排序    O(n^2)         O(n)           O(n^2)          O(1)        In-place    穩定
希爾排序    O(n log n)     O(n log^2 n)   O(n log^2 n)     O(1)        In-place	  不穩定
歸併排序    O(n log n)     O(n log n)     O(n log n)       O(n)        Out-place   穩定
快速排序    O(n log n)     O(n log n)     O(n^2)          O(log n)    In-place    不穩定
堆排序      O(n log n)     O(n log n)     O(n log n)       O(1)        In-place    不穩定
計數排序    O(n+k)         O(n+k)         O(n+k)           O(k)        Out-place   穩定
桶排序	   O(n+k)         O(n+k)         O(n^2)           O(n+k)      Out-place   穩定
基數排序    O(n+k)         O(n+k)         O(n+k)           O(n+k)      Out-place   穩定

n :表示數據範圍
k : "桶"的個數
In-place : 佔用常數內存,不佔用額外內存
Out-place : 佔用額外內存

				  |——直接插入排序
		     |——插入排序|
		     |		  |——希爾排序
		     |
		     |		  |——簡單選擇排序
 |——內部排序(使用內存)|——選擇排序|
 |                       |		  |——堆排序
 |			     |
 |			     |		  |——冒泡排序
 |			     |——交互排序|
 |			     |		  |——快速排序
 |			     |
 |			     |——歸併排序
 |			     |
 |			     |——基數排序
 | 
 |
 |——外部排序(內存和外存結合使用)

冒泡排序
思想:
1 從第一個數開始與一位對比,如果比下一位大(小)將它們位置互換
int[] mm = {2,1,5,7,4}
2,1,5,7,4 --> 1,2,5,7,4 --> 1,2,5,7,4 --> 1,2,5,4,7
2 第一輪排序結束之後,最大(最小)的那位放到了,最後一位,此過程再執行n-1次就可以完成排序
3 在外面嵌套一層for循環控制執行次數
優化:一般最後的某些位已經是排序好了的,不需要再次排序,子循環for可以不進行交換

/**
 * 測試冒泡排序算法
 * @author Administrator
 *
 */
public class BubbleSort {
	public static void main(String[] args) throws Exception {
		int[] mm = {2,1,5,7,4};
		int temp = 0;
		int length = mm.length;
		for(int j = 1;j<=mm.length;j++) {
			for(int i=0;i<mm.length-j;i++) {
				if(mm[i]>mm[i+1]) {
					temp = mm[i];
					mm[i]=mm[i+1];
					mm[i+1]=temp;
				}
				
			}
		}
		for (int i : mm) {
			System.out.print(i);
		}
	}
}

快速排序
思想:

定義第一位爲基準數,同時將第一位和最後一位分別定義爲哨兵i和哨兵j,哨兵j先開始移動,往左方向,找到比基準數小的就停在那裏,然後哨兵i纔開始移動,找到比基準數大的才停在那裏。
		初始數據:6 1 2 7 9 3 4 5 10 8       基準數:6
			  i                  j
		第一輪:  6 1 2 7 9 3 4 5 10 8
		                i       j
		然後將i和j所代表的數,位置互換,得到:
			  6 1 2 5 9 3 4 7 10 8
			        i       j
		此時,哨兵j繼續移動,遇到比基準數6小的4,停下來,然後哨兵i開始移動,遇到比基準數大的9,停下來
			 6 1 2 5 9 3 4 7 10 8
			         i   j
		交換位置 6 1 2 5 4 3 9 7 10 8
		                 i   j
		然後,哨兵j繼續開始移動,遇到3停下來,然後哨兵i開始移動,與哨兵j相遇,然後將基準數6與他們相遇的值3位置互換
		         3 1 2 5 4 6 9 7 10 8
	        到目前爲止,第一輪結束,基準數6已經找到他自己的位置了,他左邊的值比他小,他右邊的值比他大,但是,他左右兩邊的數來時亂糟糟
		第二輪,6的位置已經定了,不用動,拿出兩個數列 3 1 2 5 4和9 7 10 8,然後再用之前的方法分別對這兩個數列進行處理
			對3 1 2 5 4處理完得到:2 1 3 5 4,基準數3 已經歸位,基準數3不動,再次分裂爲兩個數列2 1 和 5 4 ,分別處理,得到1 2 和4 5 
			對9 7 10 8處理完得到:8 7 9 10,基準數9 已經歸位,基準數9不動,再次分裂爲兩個數列8 7 和 9 10 ,分別處理的到,7 8 和9 10
		最後的到數列
			1 2 3 4 5 6 7 8 9 10
	總的來說,快速排序就是通過確定一位基準數,每輪都將基準數歸位,直到最後一個基準數歸位。採用了“分治”的思想,時間複雜度爲nlogn
/**
 * 快速排序測試
 * @author Administrator
 *
 */
public class QuickSort {
	static int t = 0;
	static int[] m = {6,1,2,7,9,3,4,5,10,8};
	static int temp; 
	public static void main(String[] args) throws Exception {
		long start = System.currentTimeMillis();
		QuickSort quickSort = new QuickSort();
		quickSort.quick(0,9);
		for (int i : m) {
			System.out.print(i);
		}
		System.out.println();
		long end = System.currentTimeMillis();
		System.out.println(end-start);
	}
	
	public static void quick(int left,int right) {
		if(left>right) 
			return ;
		//設置基準數
		temp = m[left];
		
		//設置哨兵
		int i = left;
		int j = right;
		while(i!=j) {
			while(m[j]>=temp&&i<j) {
				j--;
			}
			while(m[i]<=temp&&i<j) {
				i++;
			}
			
			//當哨兵i和哨兵j還沒相遇
			if(i<j) {
				//將值進行互換  不使用第三個變量
				/*t = m[i];
				m[i] = m[j];
				m[j] = t;*/
				m[i] = m[i]+m[j];
				m[j] = m[i]-m[j];
				m[i] = m[i]-m[j];
				}
			
		}
		//當程序跳出while循環時,i和j已經相等,將基準值歸位
		
		t = m[left]; 
		m[left] = m[i];
		m[i] = t;
		quick(left,i-1);
		quick(i+1,right);
	}
}

選擇排序(Selection Sort)
選擇排序是最穩定的排序算法,無論什麼數據進行排序,時間複雜度都是n^2 。
思想:先在序列中選擇最小(最大)的數據放到序列的起始位置,然後再從剩餘的序列中選擇最小(最大)的數據放到已排好的序列的末位,以此類推,知道所有數據都是已排好序列。

/**
 * 選擇排序
 * @author Administrator
 *
 */
public class SelectSort {
	static int temp;
	static int number;
	public static void main(String[] args) throws Exception {
		int[] m = {6,1,2,7,9,3,4,5,10,8};
		int[] s = SelectSort.selectSort(m);
		for(int i = 0;i<s.length;i++) {
			System.out.print(s[i]);
		}
	}
	
	public static int[] selectSort(int[] m) {
		if(m.length==0)
			return m;
		for(int i = 0;i<m.length;i++) {
			temp = m[i];
			number = i;
			for(int j=i+1;j<m.length;j++) {
				if(temp>m[j]) {
					temp = m[j];
					number = j;
				}
			}
			int t = m[number];
			m[number] = m[i];
			m[i] = t;
		}
		return m;
	}
}

插入排序:
思想:拿到當前元素,在已排好序的序列中逐個比較,不合適,將這個位置的數往後挪一位,合適,插入,直至所有的元素插入結束。

    /**
 * 插入排序
 * @author Administrator
 *
 */
public class insertSort {
	public static void main(String[] args) throws Exception {
		int[] m = {6,1,2,7,9,3,4,5,10,8};
		insertSort is = new insertSort();
		int[] sort = is.Sort(m);
		for(int i = 0;i<sort.length;i++) {
			System.out.print(sort[i]);
		}
	}
	
	public int[] Sort(int[] array) {
		if(array.length == 0) {
			return array;
		}
		
		for(int i = 0;i<array.length-1;i++) {
			int index = i;
			int temp = array[i+1];
			while(index>=0&&temp<array[index]) {
				array[index+1] = array[index];
				index--;
			}
			array[index+1] = temp;
		}
		return array;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章