jquery外掛
阿新 • • 發佈:2020-11-16
歸併排序(MERGE-SORT)是利用歸併的思想實現的排序方法,該演算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞迴求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。
一、歸併排序的思想
【1】如下圖,可以看到這種結構很像一棵完全二叉樹,本文的歸併排序我們採用遞迴去實現(也可採用迭代的方式去實現)。分階段可以理解為就是遞迴拆分子序列的過程。
二、歸併排序案例
歸併排序的應用案例:給你一個數組,val arr = Array(5,4,6,3,7,2,8,9,1,0,8,3), 請使用歸併排序完成排序。
1 package com.algorithms; 2 3 import java.util.Arrays; 4 5 /** 6 * 歸併排序 7 */ 8 public class MergeSort { 9 public static void main(String[] args) { 10 int arr[] = new int[]{5,4,6,3,7,2,8,9,1,0,8,3};11 MergeSort mergeSort = new MergeSort(); 12 mergeSort.mergeSort(arr,0,arr.length-1,new int[arr.length]); 13 System.out.printf(Arrays.toString(arr)); 14 } 15 16 //分解資料 + 合併資料 17 public void mergeSort(int arr[],int left,int right,int[] temp){ 18 if(left < right){19 int mid = (left + right)/2; 20 //傳入左區間 21 mergeSort(arr,left,mid,temp); 22 //傳入右區間 23 mergeSort(arr,mid+1,right,temp); 24 //合併 25 merge(arr,left,mid,right,temp); 26 } 27 } 28 29 /* 30 * 合併方法思想:【1】、將left——mid 之間的資料 與 mid+1——right 之間的資料進行比較,並順序的放到 temp 中; 31 * 【2】上述結束後,情況一:右邊的資料遍歷結束,但是左邊的資料還有時,將左邊的全部資料複製到temp中; 32 * 情況二:左邊的資料遍歷結束,但是右邊的資料還有時,將右邊的全部資料複製到temp中; 33 */ 34 public void merge(int[] arr,int left,int mid,int right,int[] temp){ 35 //temp的下標 36 int t = 0; 37 //left 的值後續要用這裡暫存起來 38 int l = left; 39 //因為右邊的元素對mid進行了操作,所以這裡需要獲取傳入的mid並鎖死 40 int m = mid; 41 while(left <= m && mid+1 <= right){ 42 if(arr[left] < arr[mid+1]){ 43 temp[t] = arr[left]; 44 t++; 45 left++; 46 }else{ 47 temp[t] = arr[mid+1]; 48 t++; 49 mid++; 50 } 51 } 52 //情況一 53 while(left <= m){ 54 temp[t] = arr[left]; 55 t++; 56 left++; 57 } 58 //情況二 59 while(mid+1 <= right){ 60 temp[t] = arr[mid+1]; 61 mid++; 62 t++; 63 } 64 //將temp的值複製到arr中 65 //先將temp的下標還原 66 t=0; 67 while(l <= right){ 68 arr[l] = temp[t]; 69 t++; 70 l++; 71 } 72 } 73 }
三、總結
速度僅次於快速排序,為穩定排序演算法,一般用於對總體無序,但是各子項相對有序的數列。歸併排序比較佔用記憶體,但卻是一種效率高且穩定的演算法。改進歸併排序在歸併時先判斷前段序列的最大值與後段序列最小值的關係再確定是否進行復制比較。如果前段序列的最大值小於等於後段序列最小值,則說明序列可以直接形成一段有序序列不需要再歸併,反之則需要。所以在序列本身有序的情況下時間複雜度可以降至O(n)。傳統歸併排序的演算法複雜度是O(nlogn)。