博主身為大二萌新,第一次學習資料結構,自學到排序的時候,對於書上各種各樣的排序演算法頓覺眼花繚亂,便花了很長的時間盡力把每乙個演算法都看懂,但限於水平有限,可能還是理解較淺,於是便將它們逐個地整理實現出來,以便加深理解。
歸併排序就是通過將乙個具有n個key記錄的線性表,看成是具有n個有序子串行的排序疊加來實現對原有序列的排序的一種演算法。它的中間狀態就是將所有的子串行長度變為1,再將它們兩兩進行歸併,得到長度為2或1的次級子串行,之後再進行兩兩歸併,如此反覆,直到得到乙個長度為n的有序序列。這個過程包含了很多次的切分與歸併,可以通過遞迴的方式來實現。歸併排序的改進形式沒有使用耗時較大的遞迴,而是改用了迭代法,這裡我們先來討論比較基礎的遞迴法。
一共分成兩個函式,乙個是切分歸併函式,另乙個則是實現歸併的函式。
話不多說,先貼上我根據演算法實現出來的源**。
執行環境:win10&vs2015&.cpp或.c字尾檔案形式
#include "stdafx.h"
#include "stdio.h"
#include "malloc.h"
#include #include#define ok 1
#define error 0
#define maxsize 100
typedef int status;
typedef struct sqlist;
/*線性鍊錶初始化函式*/
status initsqlist(sqlist *s)
return ok;
}/*歸併排序的歸併函式*/
void merge(int sr, int tr, int i, int middle, int rightend)
if (i <= middle)
if (j <= rightend)
}/*歸併排序遞迴函式*/
void msort(int sr, int tr1, int s, int t)
}/*總體呼叫排序函式*/
void mergesort(sqlist *s)
int main()
system("pause");
return 0;
}
執行結果:
這裡的遞迴過程我思考了很久才算是徹底想清楚,下面整理給大家,以供參考。
以嚴蔚敏老師的書上的數列為例:
這些元素在前面**中對應下標為
上圖為鄙人對遞迴函式執行過程的一部分進行的整理。退出(1)與(2)的遞迴步驟以後,執行的就是merge(tr2,tr1,1,2,4)的歸併排序函式了,就是將tr2[1...2]與tr2[3...4]歸併到tr1[1...4](即上圖msort(sr,tr2,1,4)中的形參tr2)。
由此可見,所謂的將tr2排序歸併到tr1的merge函式,在退到最外層遞迴以前,都是指排序歸併到merge函式的形參tr1即實參tr2中。在最外層遞迴函式,才是將middle兩側的排好序的部分有序的tr2歸併到真正的tr1中,獲得最後的整體有序的排序結果。
另外的半部分的遞迴執行過程同理,在此就不進行贅述了。
這麼乙個看上去很簡單的歸併排序我竟然搞了這麼久才懂,也是菜的不行,但想到自己每天能比之前強上那麼一點點,就開心的不行呢。
資料結構 排序演算法之歸併排序
基本思想 將待排序的元素序列分成兩個等長的子串行,再將子串行劃分子串行,直到子串行中只有乙個元素就不用在對子序列繼續進行劃分,將劃分的每個區塊,進行排序,然後再將其歸併到乙個序列中,直到將所有的子串行歸併完成之後,則這個序列就完成了排序。1 基本思想如下所示 經過上面的劃分,從而可以看出經過劃分與歸...
資料結構 排序演算法之歸併排序
演算法思想 歸併排序是利用歸併的思想實現的排序方法,該演算法採用 分而治之 的思想將問題分成一些小的問題然後遞迴實現,最後合而為之。實現 遞迴實現 void merge int arr,const int left,const int mid,const int right,int temp whi...
資料結構之排序 歸併排序
四 歸併排序 歸併 把若干個有序的數列,合成乙個有序的數列 如二路歸併 void merge int d1,int len1,int d2,int len2,int tmp while i len1 tmp k d1 i while j len2 tmp k d2 j 1,二路歸併排序 迭代法 把待...