【Java】 大話資料結構(17) 排序演算法(4) (歸併排序) 資料結構與演算法合集 資料結構與演算法合集
阿新 • • 發佈:2018-11-13
本文根據《大話資料結構》一書,實現了Java版的堆排序。
更多:資料結構與演算法合集
基本概念
歸併排序:將n個記錄的序列看出n個有序的子序列,每個子序列長度為1,然後不斷兩兩排序歸併,直到得到長度為n的有序序列為止。
歸併方法:每次在兩個子序列中找到較小的那一個賦值給合併序列(通過指標進行操作)。當一個子序列遍歷完成後,將另一個序列中剩下數賦值給合併序列。(詳見程式碼)
歸併排序示意圖
完整Java程式碼
(含測試程式碼)
public class MergeSort { public void mergeSort(int[] arr) { if(arr==null || arr.length<=0) return; mSort(arr,0,arr.length-1); } private void mSort(int[] arr, int start, int end) { if(start==end) return; int mid=(start+end)/2; mSort(arr,start,mid); mSort(arr, mid+1, end); merge(arr,start,mid,end); } private void merge(int[] arr, int start, int mid, int end) { int[] temp=new int[end-start+1]; //存放排序號資料的臨時區域 int k=0; //臨時區域的指標 int i=start; //第一個有序區的指標 int j=mid+1; //第二個有序區的指標 while(i<=mid && j<=end) { if(arr[i]<=arr[j]) temp[k++]=arr[i++]; else temp[k++]=arr[j++]; } while(i<=mid) temp[k++]=arr[i++]; while(j<=end) temp[k++]=arr[j++]; for(k=0;k<=end-start;k++) arr[k+start]=temp[k]; } //==========測試程式碼================= public void test1() { int[] a = null; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test2() { int[] a = {}; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test3() { int[] a = { 1 }; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test4() { int[] a = { 3, 3, 3, 3, 3 }; mergeSort(a); System.out.println(Arrays.toString(a)); } public void test5() { int[] a = { -3, 6, 3, 1, 3, 7, 5, 6, 2 }; mergeSort(a); System.out.println(Arrays.toString(a)); } public static void main(String[] args) { MergeSort demo =new MergeSort(); demo.test1(); demo.test2(); demo.test3(); demo.test4(); demo.test5(); } }
null [] [1] [3, 3, 3, 3, 3] [-3, 1, 2, 3, 3, 5, 6, 6, 7]MergeSort
複雜度
時間複雜度:O(nlogn)。假設序列有n個數,遍歷一次時間複雜度為O(n),遍歷次數為二叉樹的深度log(2)n,所以時間複雜度為O(nlogn)。
歸併排序是一種比較佔用記憶體,但效率高且穩定的演算法。
更多:資料結構與演算法合集