1. 程式人生 > >歸併排序的遞迴與非遞迴的寫法

歸併排序的遞迴與非遞迴的寫法

歸併排序              歸併排序就是把兩組有序的陣列,合併成一個有序的陣列。至於如何分成兩個有序的陣列,遞迴的方法就是,把一個未排序的陣列,一直對半分,直到分成兩個陣列長度為1,然後一層一層合併上去。非遞迴的方法就是,在同一個陣列,從合併相鄰兩個長度為1的資料開始,合併到陣列的結尾,這樣算一輪,一輪完成以後,長度翻倍,合併兩個相鄰長度為2的資料組。這樣一輪一輪合併上去,也完成了歸併排序時間複雜度:nlogn                   

                                                                                   (遞迴版)

  

package demo10;
import java.util.Scanner;
public class test1 {
	static int[] A = {5 , 2, 4, 1, 3, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14};
	public static void main(String[] args) {
		sort(A, 0, 14);
		for (int i = 0; i < A.length; i++)
			System.out.println(A[i]);
	
	}
	private static void sort(int[] B, int low, int high) {
		int mid = (low + high) / 2;
		if (low < high)
		{
			sort(B, low, mid);                    //將陣列分成兩半
			sort(B, mid + 1, high);
			merge(B, low, mid, high);              //合併兩個陣列
		}
		
	}
	private static void merge(int[] b, int low, int mid, int high) { //合併兩個有序序列
        int[] temp = new int[high - low + 1];              //建立一個臨時陣列,用來儲存low-high的有序序列 
		int i = low;
		int j = mid + 1;
		int k = 0;
   
		while (i <= mid && j <= high)                     //遍歷,儲存
		{
			if (b[i] < b[j])
				temp[k++] = b[i++];
			else
				temp[k++] = b[j++];
		}

		while (i <= mid)                       //把剩餘的即最大部分依次放入陣列
			temp[k++] = b[i++];

		while (j <= high)                      //把剩餘的即最大部分依次放入陣列
			temp[k++] = b[j++];
		k = 0;
		for (i = low; i <= high; i++)
			b[i] = temp[k++]; 
		
	}	
}

                                                                              (非遞迴版)

package demo10;
import java.util.Scanner;
public class test1 {
	static int[] A = {5 , 2, 4, 1, 3, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14};
	static int N = A.length;
	public static void main(String[] args) {
		int j = 1;               //每次合併的兩個子序列的長度
		while (j < N) {
			int i = 0;                     
			while (i + j - 1 < N - 1) { //此while作用就是依次合併兩個相鄰j長的序列
				int temp;
				if (i + 2 * j - 1 < N - 1) 
					temp = i + 2 * j - 1;
				else
					temp = N - 1;
				merge(A, i, i + j - 1,  temp);
				i += (2 * j);  // 合併下一對j長的序列
			}
		j *= 2; // 合併了一輪以後 子序列的長度 翻倍 繼續合併
	}
		for (int i = 0; i < A.length; i++)
			System.out.println(A[i]);
	
		
}
	private static void merge(int[] b, int low, int mid, int high) {
		int[] temp = new int[high - low + 1];
		int i = low;
		int j = mid + 1;
		int k = 0;
		while (i <= mid && j <= high)
		{
			if (b[i] < b[j])
				temp[k++] = b[i++];
			else
				temp[k++] = b[j++];
		}

		while (i <= mid)
			temp[k++] = b[i++];

		while (j <= high)
			temp[k++] = b[j++];
		k = 0;
		for (i = low; i <= high; i++)
			b[i] = temp[k++]; 
		
	}	
	
}