1. 程式人生 > >歸併排序、希爾排序、快速排序的基本思想過程及java實現

歸併排序、希爾排序、快速排序的基本思想過程及java實現

歸併排序

歸併排序是根據將兩個有序數組合併成一個有序陣列的思想發展而來,如果兩個陣列有序,那麼只需要依次比較兩個陣列中的每個數,小的數放進空陣列中,並原陣列遊標向前移動一位進行下一次比較,直到當一個數組的遊標到達陣列尾部(也就是這個陣列被比較完了)時,直接將另一個數組剩餘的數移到新陣列即可完成排序。

public class MergeTest {
	public static void main(String[] args) {
		int[] num1 = {2,3,6,8,9,12};
		int[] num2 = {3,4,7,8};
		int[] docker = new int[10];
		
		int dex1=0,dex2=0,d=0;
		while(dex1<num1.length&&dex2<num2.length){//兩個陣列都還有元素的情況
			if(num1[dex1]<num2[dex2]){
				docker[d++]=num1[dex1++];
				//dex1++;自加在上一步實現
			}else{
				docker[d++]=num2[dex2++];
				//dex2++;
			}
		}
		//如果上面的while迴圈結束了,說明有一個數組已經為空,所以下面的迴圈可以不加dex1==num1.lengh
		while(dex1==num1.length&&dex2<num2.length){
			docker[d++]=num2[dex2++];
		}
		while(dex2==num2.length&&dex1<num1.length){
			docker[d++]=num1[dex1++];
		}
		
		for(int k:docker){
			System.out.print(k+" ");
		}
		
	}
}

希爾排序

希爾排序是插入排序的一種,也稱為縮小增量排序,是直接插入排序的改進版。直接插入排序存在的缺陷是,當一個很小的數位於陣列最右邊時,因為需要一個個進行比較(步長為1),那麼就需要比較N-1次並移動N-1次,如果是極端情況下,整個陣列是倒序排序的,這種情況下效率就變得很低了。因此,為了改良其效能,提出了希爾排序,思路是選定步長,距離為步長的一組數先進行插入排序,之後步長縮短,再次排序,直至步長為1排序後結束。以陣列為例,假設一個數組有N個元素,第一次選擇一個合適的數a作為步長(增量),把所有距離為a的倍數的元素歸為一組並對每組進行組內插入排序(注意:每組的資料在分組時並不改變在原陣列的下標,只有在插入排序時才改變)。第一次組內排序後,再選取一個合適的數b作為新的步長(b<a)進行分組,並在組內排序,接著再重複執行縮小步長並排序,直到步長為1時排序結束。

希爾排序的效率:最差為N^2

/**
 * 希爾排序
 * @author ht
 */
public class ShellSort {
	public static void main(String[] args) {
		int[] arr = { 5, 2, 3, 6, 8, 24, 16, 55, 46, 1, 9, 15, 12, 32, 52, 71, 31, 39, 22 };
		shellSort(arr);
		System.out.println("希爾排序的最終結果為:");
		for (int i : arr) {
			System.out.print(i + " ");
		}
	}

	public static void shellSort(int[] arr) {
		int len = arr.length;
		int gap = len / 2;
		while (gap > 0) {// 隨著迴圈次數增加,gap逐次減小,到1為止
			for (int i = 0; i < len - gap; i++) {// 對於每種gap值,遍歷對應的每一對值
				int j = i + gap;
				while (j - gap >= 0 && arr[j - gap] > arr[j]) {//比較每一隊值的大小關係
					int temp = arr[j - gap];
					arr[j - gap] = arr[j];
					arr[j] = temp;
					j -= gap;//依次向低位進行比較
				}
			}
			System.out.print("gap = " + gap + "時的排序結果:");
			for (int num : arr) {
				System.out.print(num + " ");
			}
			System.out.println();
			gap = gap / 2;
		}
	}
}

執行結果

快速排序

快速排序是氣泡排序的改進版,也是最好的一種內排序,在很多面試題中都會出現,也是作為程式設計師必須掌握的一種排序方法。快速排序首先選取陣列中的一個元素作為基準元素用A表示,根據A將陣列分成兩部分,比A小的放在左邊,比A大的放在右邊。具體實現方法是定義兩個遊標i和j,分別放在陣列的兩端。假設i在左j在右,它們一起向中間移動尋找,i尋找一個比A大的元素B,j尋找一個比A小的元素C,然後交換B和C。當i和j走到中間相遇時第一輪劃分結束。然後再對左右兩部分陣列分別選取各自的基準元素進行劃分,。。。