遞迴排序演算法

2022-06-12 18:33:09 字數 1981 閱讀 5439

遞迴呼叫是用相同的方法去解決更小的問題,直到問題規模小於或等於某個邊界條件時,不再進行遞迴(遞迴的出口),而是直接處理,然後不斷向下執行函式返回結果。

1.當問題小到一定規模時,可以直接求解;

2.當問題規模較大時,可以分解為若干個相互獨立的子問題,這些子問題與原問題具有相同的特徵。若不能直接解決,則可分別遞迴求解;

3.原問題的解是子問題的解的組合。

遞迴實現如下:

int binsearch(int *arr,int key,int low,inthigh) 

要點:採用分治法的策略,將已有的有序子串行合併為完全有序的序列,首先要讓子串行有序,然後再使子串行間有序,最後等到完全有序的序列。

思想:將待排序序列r[0,...n-1]分為n個長度為1的子串行,講相鄰的子串行進行歸併,得到n/2個長度為2的有序表;將這些有序序列再次歸併,得到n/4個長度為4的有序序列;如此反覆進行下去,最後得到乙個長度為n的                     有序序列。

首先要做兩步:

1.分解 

——將序列每次折半劃分

2.合併 ——將劃分後的序列段兩兩合併後排序

那麼現在我們就要解決兩個問題,怎麼分解和合併?

分析:在某趟歸併中,設各子檔案長度為length(最後乙個子檔案的長度可能小於length),則歸併前r[1..n]中共有n/length個有序的子檔案:r[1..length],r[length+1..2length],…。

注意:呼叫歸併操作將相鄰的一對子檔案進行歸併時,必須對子檔案的個數可能是奇數、以及最後乙個子檔案的長度小於length這兩種特殊情況進行特殊處理:

① 若子檔案個數為奇數,則最後乙個子檔案無須和其它子檔案歸併(即本趟輪空);

② 若子檔案個數為偶數,則要注意最後一對子檔案中後一子檔案的區間上界是n。

一趟歸併**:

void  merge(int * a,int low,int mid,int

high)

while(i<=mid)

r[p++]=a[i++];

while(j<=high)

r[p++]=a[j++];

for(p=0,i=low;i<=high;p++,i++)

a[i]=r[p];

delete r;

}

void mergepass(int *a,int n,int

length)

if(i+length<=n-1

) merge(a,i,i+length-1,n-1);//

尚有兩個子檔案,其中後乙個長度小於length,歸併最後兩個子檔案

//注意:若i≤n-1且i+length-1≥n-1時,則剩餘乙個子檔案輪空,無須歸併

}

二路歸併**:

//

自底向上

void mergesort(int *a,int

n)

基本思想:首先從待排序中選定乙個基數,通過關鍵字和基數的比較將待排序列劃分為兩個子串行,其中在基數前的都不大於基數;我們發現每次都是把基數歸位。

劃分演算法:

int partition(int arr,int low,int

high)

arr[low] =temp;

return

low;

}

遞迴核心**:

void qsort(int arr,int s,int

t)}

遞迴排序演算法

1 歸併排序 歸併排序用的是分治法,即將要排序的陣列分而治之。如圖所示 簡單的 如下 public class merge publicvoid mergearray inta,int first,intmid,int last while i m while j n for i 0 i k i 將...

遞迴與排序演算法

程式 資料結構 演算法 遞迴是一種應用非常廣泛的演算法。很多資料結構和演算法的編碼實現都要用到遞迴。排序演算法最經典最常用的冒泡插入選擇,時間複雜度都為o 乙個問題的解可以分解為幾個子問題的解 這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 存在遞迴終止條件 分成遞和歸來看,我覺得和...

快速排序 遞迴演算法

快速排序原理 從乙個陣列中任意挑選乙個元素 通常為最左邊的元素 作為基準數,將剩下的元素和基準數進行比較,將小於等於中軸元素的放到基準數的左邊,經大於 中軸元素的放到基準數的右邊,然後以當前基準數的位置為界,將左半部分陣列和右 半部分陣列堪稱兩個新的陣列,重複上述操作,直到子陣列的元素個數小於等於1...