歸併排序的優化

2021-08-19 14:00:44 字數 1448 閱讀 5677

上節中的陣列合併**中,沒有做任何判斷就進行了陣列的合併,實際上當陣列1的最後乙個元素小於陣列2的第乙個元素時,根本不需要挨個對比、複製元素進行合併操作,此時陣列1和陣列2本來就是有序的,不需要合併,因此**改為(部分**)

mergesort1(list1, listsize1);

mergesort1(list2, listsize2);

if (list1[listsize1 - 1] > list2[0])

merging1(list1, listsize1, list2, listsize2);

在遞迴的**中一直遞迴到陣列長度為1為止,之後進行合併操作,實際上,當陣列長度較小時可以使用插入排序進行較短陣列的排序,不用遞迴到底

templatevoid mergesort1(t k, int len) 

t *list1 = k;

int listsize1 = len / 2;

t *list2 = k + len / 2;

int listsize2 = len - listsize1;

mergesort1(list1, listsize1);

mergesort1(list2, listsize2);

if (list1[listsize1 - 1] > list2[0])

merging1(list1, listsize1, list2, listsize2);

}

上節的歸併排序使用遞迴的方式實現,遞迴頻繁的呼叫函式會消耗一定時間,並且對棧的操作也很多,大多數遞迴演算法都可以轉化成迭代的方式實現。遞迴是將陣列從上到下的層層分組,減小長度,那麼迭代實現的話則是從下到上,設定乙個間距,初始為1,則以1為單位進行元素的合併,接下來間距乘以2,以2個元素一組進行合併,重複上述步驟,直至間距大於陣列長度。

上圖以2個元素一組為例,設定4個指標,為

int leftmin, leftmax, rightmin, rightmax
分別指向兩組元素的對應位置,當然也可以讓leftmax和rightmax分別指向每組的最後乙個元素,而不是最後乙個元素的下乙個位置,合併時需要temp陣列,合併過程會出現兩個陣列中一邊先遍歷結束的情況:當左邊的先遍歷結束時,因為右邊陣列的剩餘元素本來就應該待在當前的位置,因此無需處理;當右邊的元素先遍歷結束時,如圖中對勾代表元素已經放到正確的位置,x代表還沒有遍歷的元素,那麼將左邊陣列未遍歷的元素放到右邊陣列中對應的位置處即可,省去了複製到temp陣列再複製回原陣列的操作。

templatevoid mergesortiter(t k, int len) }}

經過測試迭代實現的歸併排序還是比遞迴實現的要快的。

歸併排序以及歸併排序的優化

1 歸併排序的實現 歸併排序也利用了分治法的思想,首先將序列分成左右兩部分,將左右兩部分分別排序,然後將有序的兩個子串行進行合併 即merge操作 程式是遞迴進行的,主函式實現如下 歸併排序主函式 void merge sort int a,int first,int last else while...

歸併排序的優化 自然歸併排序

不知道怎麼將這個演算法思想表達的更好,也不知道自己的理解的是否對 黑體的注釋是普通的自然歸併,從相鄰長度為1的子陣列段進行合併也就是一開始將每兩個相鄰元素進行歸併,然後再相鄰四個元素左右兩組都有序的合併成4個有序的.自下向上不斷往上歸併直到有序 自然合併排序是合併排序演算法的一種改進.自然合併排序 ...

歸併排序法及優化

將陣列分成兩半,然後分別對其排序 在將兩部分在分別分成兩半,然後對其排序 直到每部分只剩下乙個元素 最後再使用遞迴merge兩邊的陣列。merge時,需要借助三個指標。乙個指向左半部分 乙個指向右半部分 乙個指向輔助陣列。class solution int j low 左半部分指標 int k m...