分治法(归并排序与最大子段和)

1、归并排序

#include<stdio.h>
#include<sched.h>

void Merge(int A[],int p,int q,int r){
    int i, j, k;
    
    int L[50], R[50]; 
    int n1 = q - p + 1, n2 = r - q; // 左右子序列长度 
    for(i = 0; i < n1; i ++){ // 把左子序列放入 L[] 
        L[i] = A[p + i];
    }
        
    for(j = 0; j < n2; j++){ // 把右子序列放入 R[] 
        R[j] = A[q + j + 1];
    }
        
    L[n1] = INT_MAX;
    R[n2] = INT_MAX;
    
    i = 0;
    j = 0;
    for(k = p; k < r + 1; k++){
        if(L[i] < R[j]){ // 比较找出最小的。。 
            A[k] = L[i];
            i++;
        }
        else {
            A[k] = R[j];
            j++;
        }
    }
}

void MergeSort(int A[], int p, int r){ // p r 边界值
    int q; // 中间值 
    if(p < r){ // 分解成子问题 
        q = (p + r)/2;
        MergeSort(A, p, q);
        MergeSort(A,q + 1,r);
        
        Merge(A, p, q, r);
    }
}



int main() {
    int A[] = {4, 1, 3, 6, 7, 5, 2, 9};
    MergeSort(A, 0, 7);
    
    int i;
    for(i = 0; i < 8; i ++) {
        printf("%d ",A[i]);
    }
    
    return 0;
}

2、最大子段和

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

int MaxSubSum(int *Array, int left, int right){
    int sum = 0;
    int i;
    
    if (left == right) { // 分解到单个整数,不可继续分解 
        if (Array[left] > 0)
            sum = Array[left];
        else
            sum = 0;
    } else {
        /* 从 left 和 right 的中间分解数组*/ 
        int center = (left + right) / 2; // 划分的位置 
        int leftSum = MaxSubSum(Array, left, center);
        int rightSum = MaxSubSum(Array, center + 1, right);
        
        /* 计算包含 center 的最大值、判断是情形1、情形2还是情形3 */ 
        int s1 = 0;
        int lefts = 0;
        for (i = center; i >= left; i--) {
            lefts += Array[i];
            if (lefts > s1)
                s1 = lefts;
        }
        
        int s2 = 0;
        int rights = 0;
        for (i = center + 1; i <= right; i++){
            rights += Array[i];
            if (right > s2)
                s2 = rights;
        }
        
        sum = s1 + s2;
        
        // 情形1 
        if (sum < leftSum)
            sum = leftSum;
            
        // 情形2 
        if (sum < rightSum)
            sum = rightSum;
    }
    
    return sum;
} 

int main() {
    int *Array = (int *) malloc(6 * sizeof(int)); // malloc 分配Array所需空间 
    Array[0] = -2;
    Array[1] = 11;
    Array[2] = -4;
    Array[3] = 13;
    Array[4] = -5;
    Array[5] = -2;
    
    int result = MaxSubSum(Array, 0, 5);
    printf("%d",result);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值