最近學習《演算法導論》,整理一下每章的筆記,並且會將書上的虛擬碼用C語言實現。 分治模式的一般步驟: (1)分解(Divide):將原問題分解成一系列自問題
(2)解決(Conquer):遞迴的解各子問題。若問題足夠小,則直接求解(遞迴結束的條件)
(3)合并(Combine):將子問題的結果合并成原問題的解 對于歸並排序的遞迴實現,則完全依照了上述模式:
(1)分解:將N個元素分成個含N/2個元素的子序列
(2)解決:用合并排序法對兩個子序列遞迴的排序
(3)合并:合并兩個已排序的子序列以得到排序結果代碼如下(ps:遞迴實現了歸併排序,同時增加了二分尋找的代碼):
#include <stdio.h>#define MAX 65535void Merge(int *A,int p,int q,int r);void MergeSort(int *A,int p,int r);void PrintArray(int *A,int size);int BinarySearch(int *A,int key,int begin,int end);int main(void){int i,size,key,location;int A[1000]={0};printf("請輸入排序數組的大小: ");scanf("%d",&size);for(i = 0; i < size; i++){scanf("%d",&A[i]);}//歸併排序並列印數組MergeSort(A,0,size-1);printf("排序好的數組元素: ");PrintArray(A,size);printf("請輸入尋找元素: ");scanf("%d",&key);location=BinarySearch(A,key,0,size-1);if( location == -1 ){printf("元素沒有找到\n");}else{printf("元素的位置在%d\n",location);}return 0;}void Merge(int *A,int p,int q,int r){int i,j,k;//定義數組A[p..q]和A[q+1..r]的長度int n1 = (q - p + 1);int n2 = (r - q);int Larray[n1],Rarray[n2];for(i = 0; i < n1; i++){Larray[i] = *(A + p + i);}for(j = 0; j < n2; j++){Rarray[j] = *(A + q +1 + j);}//哨兵位置Larray[n1] = MAX;Rarray[n2] = MAX;for(i = 0,j = 0,k = p; k <= r; k++){if(Larray[i] <= Rarray[j]){*(A + k) = Larray[i++];}else{*(A + k) = Rarray[j++];}}}/** * Description:歸併排序主流程函數 */void MergeSort(int *A,int p,int r){int q;if(p < r){q = (int)( p + r ) / 2;MergeSort(A,p,q);MergeSort(A,q+1,r);Merge(A,p,q,r);}}/** * Description:列印數組 */void PrintArray(int *A,int size){int i;for(i = 0; i < size; i++){printf("%d ",*(A+i));}printf("\n");}/** * Description:二分尋找 */int BinarySearch(int *A,int key,int begin,int end){while( begin <= end ){int mid = ( begin + end ) / 2; if(key > *(A + mid)){begin = mid + 1 ;}else if(key < *(A + mid)){end = mid - 1;}else{return mid+1;}}return -1;}