歸併排序的實現

2021-09-18 05:41:27 字數 2182 閱讀 7991

歸併排序的思想:分治法;

分治法的思想是,當我們求解乙個大問題需要很多的時間,並且方式很難實現,我們發現,如果將這個如果將這個大問題分解成若干個小問題,則問題就變得簡單很多,這些小問題求解的同時,原問題也得以求解,我們將乙個大問題逐步分解成若干個小問題求解的思想,就是分治法,同時也是遞迴思想。

歸併排序演算法就是利用了這種思想。

首先對於乙個大的資料集,我們不好排序,我們將這個資料集一分為二,分成兩個小的資料集,我們假設,如果這兩個資料集排序完成,剩下的工作就是講這兩個有序的資料集合並成乙個有序的的資料集,

於是我們的當下任務可以分成兩個,首先第乙個是,排序這個兩個小的資料集,然後的任務是,將這兩個小的資料集整合到乙個有序的資料集。

解決第乙個任務:拆分

如果原來的資料集很大,我們拆分成兩個資料集的時候,發現,還是不好排序,怎麼辦,答案很簡單,說明它還不夠小,於是,我們對著兩個資料集,也採用相同的做法,在拆分,以此類推,一直到我們的拆分的資料集只有乙個資料為止,這個時候,我們發現,對於只有乙個資料元素的資料集,它的順序也就已經確定了,我們的排序也就完成了。也就是說只要我們對資料不停的拆分,最後將每乙個資料集拆分成只有乙個資料元素的時候,其排序過程其實就已經完成了。

解決第二個任務:合併

經過上乙個步驟,我們就得到了兩個有序的資料集合,然後,我們的任務就是將這兩個有序的資料集合並成乙個有序的資料集合。這裡我們舉乙個例子,桌子上有兩副有序的牌,我們要將他們合併成一副有序的牌,我們該怎麼做呢,很簡單,假設兩副陪得順序都是從小到大排放,小的在上面,首先,我們分別從兩副牌的頂端,各取乙個,然後比較誰打誰小,將小的放到手中,大的不動,然後在從兩副牌的頂端在取兩張牌,再比,以此類推,知道一副牌比完,或者兩副牌都同時比完,如果其中的一副牌先比完,則將剩下的牌就不用比了,直接放到手中就行了,這時,手中的牌就是合併好的有序的牌了。

好了原理我們說的差不多了,然後我們來說一下如何用**實現呢?

通過上面分析,我們發現,第乙個任務似乎不是很難,我們先完成拆分。

public static void mergerinside(int arr, int start, int end) 

}

通過上面的分析我們知道,這個方法是乙個遞迴的過場,也就是在拆分完成到最後,左右兩邊的資料集都是已經排好序的,然後我們進行合併,合併的結果也是乙個有序的資料集。這樣,我們的遞推關係就可以正確進行下去了。

其實,拆分並不是最難的部分,我們的關鍵重點是合併。

public static void merger(int arr, int start, int middle, int end) 

//為右邊陣列賦值

for (; j < right_len; j++)

i = 0;

j = 0;

int k = start;

//從左右兩邊的頂端分別取乙個資料,然後比較,將小的放到第乙個位置

while (i < left_len && j < right_len) else

}//右邊的資料用完了,然後直接將左邊的資料複製到陣列中

if (i < left_len)

//左邊資料用完了,然後直接將右邊的陣列複製到陣列中

if (j < right_len)

}

優化

public class demo ;

//排序陣列

mergersort(arr);

for (int i : arr)

}public static void mergersort(int arr)

public static void mergerinside(int arr, int start, int end,int leftarr,int rightarr)

}public static void merger(int arr, int start, int middle, int end,int leftarr,int rightarr)

for (; j < right_len; j++)

i = 0;

j = 0;

int k = start;

while (i < left_len && j < right_len) else

}if (i < left_len)

if (j < right_len)

}}

歸併排序實現

1,我認為歸併排序是分治思想的運用,先是把要排序的數列分成兩半,分別對這兩半進行歸併排序,一步步分下去,當分到規模為1時,開始合併兩個已經有序的陣列。2,主要的 是兩個已經有序的陣列的合併,其中涉及的有空間申請的問題和哨兵的使用。具體看 這是初寫的 存在的問題有每次迭代都申請了空間且沒釋放,而且沒有...

歸併排序實現

看到個帖子寫的歸併排序,記錄一下,特別是對鍊錶的使用。歸併的排序分為三步走 1 分割,2 遞迴,3 合併。陣列歸併排序 歸併排序三步走 1 分割子問題 2 遞迴 3 合併子問題。include stdafx.h includeusing namespace std void mergearray i...

歸併排序實現

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...