“分而治之” 求最大子列和 -遞歸

mooc課程《數據結構》第一章實例

示例代碼:

    int Max3( int A, int B, int C )
    { /* 返回3個整數中的最大值 */
        return A > B ? A > C ? A : C : B > C ? B : C;
    }
     
    int DivideAndConquer( int List[], int left, int right )
    { /* 分治法求List[left]到List[right]的最大子列和 */
        int MaxLeftSum, MaxRightSum; /* 存放左右子問題的解 */
        int MaxLeftBorderSum, MaxRightBorderSum; /*存放跨分界線的結果*/
     
        int LeftBorderSum, RightBorderSum;
        int center, i;
     
        if( left == right )  { /* 遞歸的終止條件,子列只有1個數字 */
            if( List[left] > 0 )  return List[left];
            else return 0;
        }
     
        /* 下面是"分"的過程 */
        center = ( left + right ) / 2; /* 找到中分點 */
        /* 遞歸求得兩邊子列的最大和 */
        MaxLeftSum = DivideAndConquer( List, left, center );
        MaxRightSum = DivideAndConquer( List, center+1, right );
     
        /* 下面求跨分界線的最大子列和 */
        MaxLeftBorderSum = 0; LeftBorderSum = 0;
        for( i=center; i>=left; i-- ) { /* 從中線向左掃描 */
            LeftBorderSum += List[i];
            if( LeftBorderSum > MaxLeftBorderSum )
                MaxLeftBorderSum = LeftBorderSum;
        } /* 左邊掃描結束 */
     
        MaxRightBorderSum = 0; RightBorderSum = 0;
        for( i=center+1; i<=right; i++ ) { /* 從中線向右掃描 */
            RightBorderSum += List[i];
            if( RightBorderSum > MaxRightBorderSum )
                MaxRightBorderSum = RightBorderSum;
        } /* 右邊掃描結束 */
     
        /* 下面返回"治"的結果 */
        return Max3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
    }
     
    int MaxSubseqSum3( int List[], int N )
    { /* 保持與前2種算法相同的函數接口 */
        return DivideAndConquer( List, 0, N-1 );
    }

 

模仿代碼:

#include <stdio.h>
#include <stdlib.h>

int Max3(int a, int b, int c){
	return a > b ? (a>c ? a:c) : (b>c ? b:c);
}

int MaxSubseqSum(int li[],int a,int b){
	int lSum,rSum;
	int lbSum,rbSum,lb,rb;
	
	int i;
	int center;
	
	if(a == b){                         //遞歸終止的條件 
		if( li[a] > 0 ){
			return li[a];
		}else{
			return 0;                           
		}
	}
	
	center = (b+a)/2;
	
	lSum = MaxSubseqSum(li,a,center);
	rSum = MaxSubseqSum(li,center+1,b);
	
	lbSum = 0; lb = 0;
	for(i=center+1; i<=b; i++){
		lb += li[i];
		if(lb > lbSum){
			lbSum = lb;
		}
	}
	
	rbSum = 0; rb = 0;
	for(i=center; i>=a; i--){
		rb += li[i];
		if(rb > rbSum){
			rbSum = rb;
		}
	}
	
	return Max3(rbSum+lbSum, rSum, lSum);
	
}

int main() {
	int li[10] = {2,3,-4,12,-3,-5,4,5};
	int maxsub;
	maxsub = MaxSubseqSum(li,0,7);
	printf("最大子列和:%d",maxsub);
	return 0;
}

小白第一次理解到遞歸的終止條件

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章