java實現排序演算法之歸併排序(2路歸併)
阿新 • • 發佈:2018-12-23
歸併排序:“歸併”的含義就是將兩個或兩個以上的有序表合併成一個新的有序表,假定待排序表含有n個記錄,則可以看成是n個有序的子表,每個子表的長度為1,然後兩兩歸併,得到n/2個長度為2或1的有序表,然後在兩兩歸併,如此重複,直到合併成一個長度為n的有序表為止,這就是2路歸併排序。這是一個由少到多的歸併過程,但是計算機中一個數組長度是固定的,我們反過來看,先假設一個數組可以分成兩個有序的子表,然後將兩個子表合併後陣列有序,然後每一個子表又可分為兩個有序的子表,然後合併子表有序,依次類推,將陣列分解,直到每一個子表均含有一個元素時,子表有序,合併仍有序,這不就是遞迴的思想麼?因此我們常用遞迴的方法來實現2路歸併排序。
穩定性:穩定
時空複雜度與初始狀態是否有關:無關
時間複雜度:每一趟歸併時間複雜度O(n),共需進行log2^n趟,因此時間複雜度為O(nlog2^n)
空間複雜度:額外複製一遍目標陣列用於匹配,因此空間複雜度為O(n)
java實現程式碼:
public static void main(String[] args) { int []a={4,9,2,7,1,8,9,5,3}; mergeSort(a, 0, a.length-1); System.out.println(Arrays.toString(a)); } public static void mergeSort(int[]a,int low,int high ){ if(low<high){//遞迴結束條件 int mid=(low+high)/2; mergeSort(a, low, mid);//左子表遞迴排列有序 mergeSort(a,mid+1,high);//右子表遞迴排列有序 merge(a,low,mid,high);//將兩有序子表合併 } } public static void merge(int []a,int low,int mid,int high){//兩有序子表合併方法 int [] temp=new int[9];//這裡把要排序陣列copy一份,用來比較,原來的陣列用來儲存比較後的資訊 for(int i=low;i<=high;i++){//注意這裡copy時,下標是從low開始的,要是為了保證copy的陣列下標與目標陣列下標一致,這樣是為了方便後面的比較的下標操作 temp[i]=a[i];//當然copy的陣列儲存時也可以從0開始儲存,但是這樣就要注意後面的比較操作時,i就不是小於mid了,而是小於mid-low,j也不是小於high,j是小於high-low } int i=low,j=mid+1,k=low;//把陣列分為前後相同的兩端進行比較。i指向前半段,j指向後半段,k指向要儲存的位置 for(;i<=mid&&j<=high;k++){//比較 if(temp[i]<temp[j])a[k]=temp[i++]; else a[k]=temp[j++]; } while(j<=high)//若第一個表沒檢測完,複製 a[k++]=temp[j++]; while(i<=mid)//若第二個表沒檢測完,複製 a[k++]=temp[i++]; } }
謝謝觀看!