遞迴呼叫是用相同的方法去解決更小的問題,直到問題規模小於或等於某個邊界條件時,不再進行遞迴(遞迴的出口),而是直接處理,然後不斷向下執行函式返回結果。
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,inthigh)
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,intt)}
遞迴排序演算法
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...