算法学习(排序四)最大子数组问题

来源:互联网 发布:php培训机构哪家好 编辑:程序博客网 时间:2024/05/18 21:12

使用分治策略解决最大子数组问题
使用分治技术意味着我们要将子数组划分为两个规模相等的子数组,比如分为{low, mid}和{mid+1,high}两部分,如此,数组{low,high}的子数组所处的位置必然有三种情况:

. 完全位于{low, mid}中. 完全位于{mid+1,high}中. 跨越中点mid

因此,在使用递归的时候,还需要在判断跨越中点的情况

/** 创建一个结构体,包含左下标,右下标和它们的和 */typedef struct{    int low;    int high;    int sum;} ResultData;/** 该函数返回一个跨越中点的最大子数组的ResultData @param array 选定的数组 @param low 左下标 @param mid 中下标,一般为(low + high) / 2 @param high 右下标 @return 返回ResultData,包含左右下标和它们的和 */ResultData crossingSubArray (int *array, int low, int mid, int high){    ResultData result;    //TODO 1.初始化左侧数据    int leftSum = -INT_MAX;    int sum = 0;    int index = 0;    //TODO 2.获取到左侧的最大值和坐标    for (int i = mid; i >= low; i--)    {        sum = sum + array[i];        if (sum > leftSum)        {            leftSum = sum;            index = i;        }    }    result.low = index;    //TODO 3.初始化右侧数据    int rightSum = -INT_MAX;    sum = 0;    //TODO 4.获取到右侧的最大值和坐标    for (int i = mid + 1; i <= high; i++)    {        sum = sum + array[i];        if (sum > rightSum)        {            rightSum = sum;            index = i;        }    }    result.high = index;    result.sum = leftSum + rightSum;    //TODO 5.返回保存的ResultData    return result;}/** 该函数返回给定数组中的最大子数组的下标和它们的和 @param array 给定的数组 @param low 左侧下标 @param high 右侧下标 @return 返回包含下标与和的ResultData */ResultData maximumSubArray (int *array, int low, int high){    //TODO 1.当左下标等于右下标时,代表此时的数组中仅有一个元素,其中的和为此元素    if (high == low)    {        ResultData result;        result.low = low;        result.high = high;        result.sum = array[low];        return result;    }    else    {        //TODO 2.初始化数据        int mid = (high + low) / 2;        ResultData leftResult;        ResultData rightResult;        ResultData crossResult;        //TODO 3.获取左侧最大数组,右侧最大数组,再获取通过中点的最大子数组        leftResult = maximumSubArray(array, low, mid);        rightResult = maximumSubArray(array, mid + 1, high);        crossResult = crossingSubArray(array, low, mid, high);        //TODO 4.返回三个中最大的一个        if ((leftResult.sum >= rightResult.sum) && (leftResult.sum >= crossResult.sum))            return leftResult;        else if ((rightResult.sum >= leftResult.sum) && (rightResult.sum >= crossResult.sum))            return rightResult;        else            return crossResult;    }}

参考资料《算法导论》

原创粉丝点击