1.歸併排序
歸併排序,顧名思義就是將兩個序列合併到一起,並且使之有序。該演算法是分治法的乙個典型應用,其主要思想是將已有序的兩個子串行合併,在這個過程中,對其元素進行比較排序,從而得到乙個完整的有序的序列。也就是先要保證小範圍的資料有序,再使大範圍的序列有序。
因此,若要使用歸併排序對乙個序列進行排序,採用分治法思想,需要先將比較大的原始序列劃分為較小的序列,使較小的序列有序。分出來的序列越小,對子序列的排序就越簡單。例如,對於每個序列只包含兩個資料的序列,只需要比較一次,就可以獲得有序序列。
對於乙個包含了n個記錄的序列,通常現將序列視為n個小序列,使相鄰的兩個小序列兩兩比較並歸併,如此就有了n/2個次小的序列。每次排序歸併都使子串行的數量減半,當子串行的數量為2時,再執行一次排序歸併,就可以使原始序列成功為乙個有序序列。這種的方法稱為2路歸併排序。
歸併排序需要乙個原始序列大小的輔助空間,在排序過程中,將本輪排序過程中的元素賦值給中間變數,當排序結束之後,再從中間變數中取值賦給原始資料。若在排序過程中,乙個序列的資料已經排序完畢,另外乙個序列還有資料剩餘,此時可以終止比較,將序列中剩餘資料逐個賦值給中間變數。
假設需要歸併排序的兩個序列分別為sub1和sub2(這兩個序列已經各自有序),設其中元素的下標分別為i和j,元素個數分別為a和b;設定輔助空間變數tmp,其中元素對應的下標為k。則歸併步驟如下:
(1)初始時i=0,j=0,k=0。
(2)比較sub1[0]和sub2[0]:
若sub1[0]>sub2[0],使tmp[0]=sub2[0],i=i+1,k=k+1;
若sub1[0]
#include
#include
//------------------方法一:遞迴實現------------------------
//歸併兩個序列的演算法
void merge(int* arr, int* tmp, int start, int mind, int end)
//若乙個序列指標走到最後,另外乙個指標未走到最後,直接複製
while (i != mid + 1)
tmp[k++] = arr[i++];
while (j != end + 1)
tmp[k++] = arr[j++];
//將中間變數陣列中儲存的值賦值給原始陣列
for (i = start; i <= end; i++)
arr[i] = tmp[i];
}//2路歸併排序
//遞迴呼叫歸併排序
void mergesort(int* arr, int* tmp, int start, int end)
}//------------------非遞迴實現-------------------
void mergesort(int* arr, int n)
for (i = 1; i < n; i *= 2)
next = 0;
while (left_min < left_max&&right_min < right_max)
while (left_min < left_max)
arr[--right_min] = tmp[--left_max];
while (next>0)
arr[--right_min] = tmp[--next];}}
}
內部排序之歸併排序(MergingSort)
將兩個已經排序好的有序列表合併成乙個新的有序表。根據分治策略,我們會發現從上往下,就是將乙個亂序表一直遞迴劃分,劃分到最後就只剩乙個元素,顯然有序。從底下往上看,整個演算法就像分治策略中的最大子陣列問題。最大子陣列問題 整個演算法分為兩個部分,乙個是對兩個有序子表的合併 乙個是對亂序表的劃分。合併 ...
4 內部排序 歸併排序
歸併排序 歸併排序和快速排序這兩種演算法都採用了分治的思想,且速度僅次於 快速排序 為穩定排序演算法,一般用於對總體無序,但是各子項相對有序的 數列,其具體思想如下 1 將序列每相鄰兩個數字進行歸併操作 merge 形成 n 2 個序列,排序後每個序列包含兩個元素 2 將上述序列再次歸併操作,形成 ...
內部排序(四)歸併排序
總述 歸併排序 merging sort 中歸併是將兩個或兩個以上的有序表組合成乙個新的有序表。歸併排序我們主要 2 路歸併排序。2 路歸併排序 過程 假設初始序列含有n個記錄,則可看成是n個有序的子串行,每個子串行的長度為1,然後兩兩歸併,得到ceil n 2 個長度為2或1的有序子串行 再兩兩歸...