歸併排序詳解

2021-06-21 15:00:24 字數 2168 閱讀 4187

一.概念:

歸併是指將若干個已排序的子檔案合併成乙個有序的檔案。

二.基本思路:

設兩個有序的子檔案(相當於輸入堆)放在同一向量中相鄰的位置上:r[low..m],r[m+1..high],先將它們合併到乙個區域性的暫存向量r1(相當於輸出堆)中,待合併完成後將r1複製回r[low..high]中。

合併過程中,設定i,j和p三個指標,其初值分別指向這三個記錄區的起始位置。合併時依次比較r[i]和r[j]的關鍵字,取關鍵字較小的記錄複製到r1[p]中,然後將被複製記錄的指標i或j加1,以及指向複製位置的指標p加1。

重複這一過程直至兩個輸入的子檔案有乙個已全部複製完畢(不妨稱其為空),此時將另一非空的子檔案中剩餘記錄依次複製到r1中即可。

三.圖形解析

首先我們來討論歸併演算法,歸併演算法將一系列資料放到乙個向量中,索引範圍為[first,last],這個序列由兩個排好序的子表構成,以索引終點(mid)為分界線,以下面乙個序列為例

7,10,19,25,12,17,21,30,48

這樣的乙個序列中,分為兩個子串行 7,10,19,25  和 12,17,21,30,48,如下圖所示:

再使用歸併演算法的時候的步驟如下:

第一步:比較v[indexa]=7和v[indexb]=12,將較小的v[indexa]取出來放到臨時向量temparray中,然後indexa加1

第二步:比較v[indexa]=10和v[indexb]=12,將較小的10放到臨時變數temparray中,然後indexa++;

第三步:比較v[indexa]=19與v[indexb]=12,將較小的12存放到臨時變數temparray中,然後indexb++;

第四步到第七步:按照以上規則,進行比對和儲存,得到如下結果:

最後一步:將子表b中剩餘項新增到臨時向量temparray中

四.單執行緒程式c語言**:

#include#includevoid merge(int a,int start,int end)

main()

;int i;

sort(a,0,(sizeof(a)/sizeof(a[0])-1));//sizeof(a)/sizeof(a[0])表示陣列中元素的總個數

for(i=0;i

執行結果:

多執行緒c程式**:

#include #include #include #include #define max 10

pthread_t thread[2];//資料型別:pthread_t:執行緒控制代碼

pthread_mutex_t mut;//試圖占有互斥鎖(不阻塞操作)。即,當互斥鎖空閒時,將占有該鎖;否則,立即返回。

int number=0, i;

void *thread1()

printf("thread1 :主函式在等我完成任務嗎?\n");

pthread_exit(null);//終止當前執行緒

}void *thread2()

printf("thread2 :主函式在等我完成任務嗎?\n");

pthread_exit(null);

}void thread_create(void)//pthread_create():建立乙個執行緒

void thread_wait(void)

if(thread[1] !=0)

}int main()

//注釋參考**:執行緒

執行結果:

歸併排序詳解

歸併排序的核心思想是將兩個已經排序的序列合併成乙個序列,那如何得到兩個已經排序的序列呢?我們知道,如果乙個序列只有乙個元素,那該序列是已經排序的,這樣我們就可以利用分治的思想,將未排序的序列劃分成更小的序列,只到我們可以很方便的對小序列進行排序 比如劃分到序列只有乙個元素,或者序列很小可以方便的使用...

歸併排序 詳解

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用,歸併排序將兩個已排序的表合併成乙個表。優點1.歸併排序的效率達到了巔峰 時間複雜度為o nlogn 這是基於比較的排序演算法所能達到的最高境界 2.歸併排序是一種穩定的...

歸併排序詳解

分治法在每層遞迴時都有三個步驟 1.分解原問題為若干個子問題,這些子問題是原問題規模較小的例項 2.解決子問題,遞迴求解各子問題,如果子問題規模足夠小,則直接求解 3.合併子問題得到原問題的解。歸併排序完全遵循分治法 1.分解待排序的n個元素的序列,分成各具有n 2個元素的兩個子串行 2.使用歸併排...