【算法】_012_最大子数组_分治法

来源:互联网 发布:mysql开发培训学校 编辑:程序博客网 时间:2024/06/05 10:24

1、009_maxsubarr_divcon.h

/****************************************************************版权所有 (C)2014,长沙铁信交通科技有限公司。**文件名称:009_maxsubarr_divcon.h*内容摘要:分治法求取最大子数组*其它说明:*当前版本:V1.0*作   者:伍定湘*完成日期:2014年9月26日**修改记录1:*   修改日期:2014年9月26日*   版本号:V1.0*   修改人:伍定湘*   修改内容:创建***************************************************************/#ifndef _MAXSUBARR_DIVCON_H_ //防止头文件被重复引用#define _MAXSUBARR_DIVCON_H_/**************************************************************头文件引用**************************************************************/#include "typedef.h"//引入内置类型重定义/**************************************************************相关宏定义**************************************************************//**************************************************************相关结构体定义**************************************************************/#ifndef _MAXSUBARR_TYPEDEF_ //防止头文件被重复引用#define _MAXSUBARR_TYPEDEF_typedef struct{    INT32 iOffsetMaxBegin;    INT32 iOffsetMaxEnd;    INT32 iSumMax;}MaxSubArrTypedef;#endif/**************************************************************本程序中出现的函数的声明**************************************************************/void maxsubarr_divcon(INT32 aTarget[], const INT32 iArrLen);MaxSubArrTypedef maxsubarr_divcon_find(const INT32 aTarget[], MaxSubArrTypedef msaTarget);MaxSubArrTypedef maxsubarr_acrossing(const INT32 aTarget[], const INT32 iOffsetBegin, const INT32 iOffsetMid, const INT32 iOffsetEnd);#endif


2、009_maxsubarr_divcon.c

/****************************************************************版权所有 (C)2014,长沙铁信交通科技有限公司。**文件名称:009_maxsubarr_divcon.c*内容摘要:分治法求取最大子数组*其它说明:*当前版本:V1.0*作   者:伍定湘*完成日期:2014年9月27日**修改记录1:*   修改日期:2014年9月27日*   版本号:V1.0*   修改人:伍定湘*   修改内容:创建***************************************************************//**************************************************************头文件引用**************************************************************/#include "typedef.h"//引入内置类型重定义#include "009_maxsubarr_divcon.h"#include <stdio.h>/**************************************************************全局变量定义**************************************************************//**************************************************************函数实现**************************************************************//***********************************************************************功能描述:分治法求取最大子数组*输入参数:aTarget - 目标数组*        iArrLen - 目标数组的长度*输出参数:*返回值:*其它说明:*修改日期           版本号         修改人        修改内容* ---------------------------------------------------------------------*2014年9月27日      V1.0          伍定湘        创建***********************************************************************/void maxsubarr_divcon(INT32 aTarget[], const INT32 iArrLen){MaxSubArrTypedef msaTarget = { 0, iArrLen - 1, 0 };msaTarget = maxsubarr_divcon_find(aTarget, msaTarget);printf("iSumMax = %d\n", msaTarget.iSumMax);printf("iOffsetMaxBegin = %d\n", msaTarget.iOffsetMaxBegin);printf("iOffsetMaxEnd = %d\n", msaTarget.iOffsetMaxEnd);}/***********************************************************************功能描述:分治法求取最大子数组*输入参数:aTarget - 目标数组*        msaTarget - 上一级最大子数组参数*输出参数:*返回值:*其它说明:*修改日期           版本号         修改人        修改内容* ---------------------------------------------------------------------*2014年9月27日      V1.0          伍定湘        创建***********************************************************************/MaxSubArrTypedef maxsubarr_divcon_find(const INT32 aTarget[], MaxSubArrTypedef msaTarget){/* 单元素数组直接返回, 并同时结束了迭代 */if (msaTarget.iOffsetMaxBegin == msaTarget.iOffsetMaxEnd){msaTarget.iSumMax = aTarget[msaTarget.iOffsetMaxBegin];return(msaTarget);}/* 取中点 */INT32 mid = (msaTarget.iOffsetMaxBegin + msaTarget.iOffsetMaxEnd) / 2;/* 迭代获取左侧最大子数组 */MaxSubArrTypedef msaLeft = {0, 0, 0};//max初始值为0的前提条件是数组值至少有一个正数if (mid > msaTarget.iOffsetMaxBegin)//if语句负责过滤引起'起点大于终点'的情况, 并同时结束了迭代{msaLeft.iOffsetMaxBegin = msaTarget.iOffsetMaxBegin;msaLeft.iOffsetMaxEnd = mid - 1;msaLeft.iSumMax = 0;msaLeft = maxsubarr_divcon_find(aTarget, msaLeft);}/* 迭代获取右侧最大子数组 */MaxSubArrTypedef msaRight = { 0, 0, 0 };if (mid < msaTarget.iOffsetMaxEnd)//if语句负责过滤引起'起点大于终点'的情况, 并同时结束了迭代{msaRight.iOffsetMaxBegin = mid + 1;msaRight.iOffsetMaxEnd = msaTarget.iOffsetMaxEnd;msaRight.iSumMax = 0;msaRight = maxsubarr_divcon_find(aTarget, msaRight);}/* 迭代获取跨中点最大子数组 */MaxSubArrTypedef msaAcrossMid = maxsubarr_acrossing(aTarget, msaTarget.iOffsetMaxBegin, mid, msaTarget.iOffsetMaxEnd);/* 获取三者中和最大的 */msaTarget = msaAcrossMid;msaTarget = msaTarget.iSumMax > msaLeft.iSumMax ? msaTarget : msaLeft;msaTarget = msaTarget.iSumMax > msaRight.iSumMax ? msaTarget : msaRight;/* 返回三者中和最大的 */return(msaTarget);}/***********************************************************************功能描述:分治法求取跨过中点的最大子数组*输入参数:aTarget - 目标数组*        iOffsetBegin - 目标数组的起点下标*        iOffsetMid - 目标数组跨过的中点下标*        iOffsetEnd - 目标数组的终点下标*输出参数:*返回值:*其它说明:*修改日期           版本号         修改人        修改内容* ---------------------------------------------------------------------*2014年9月27日      V1.0          伍定湘        创建***********************************************************************/MaxSubArrTypedef maxsubarr_acrossing(const INT32 aTarget[], const INT32 iOffsetBegin, const INT32 iOffsetMid, const INT32 iOffsetEnd){    /* 中点左侧参数 */    INT32 iOffsetLeft = iOffsetMid;    INT32 iOffsetMaxLeft = iOffsetMid;    INT32 iSumMaxLeft = aTarget[iOffsetMid];    /* 中点右侧参数 */    INT32 iOffsetRight = iOffsetMid;    INT32 iOffsetMaxRight = iOffsetMid;    INT32 iSumMaxRight = aTarget[iOffsetMid];    /* 求和参数 */    INT32 iSum;    INT32 iOffset;    /* 输出结果 */    MaxSubArrTypedef msaAcrossMid = { iOffsetMid, iOffsetMid, aTarget[iOffsetMid] };/* 反向扫描包含iOffsetMid元素左侧的最大子数组 */    for (; iOffsetLeft >= iOffsetBegin; iOffsetLeft--)    {        iSum = 0;        for (iOffset = iOffsetLeft; iOffset <= iOffsetMid; iOffset++)//求取数组从下标iOffsetLeft到iOffsetMid的元素总和,注意:请勿遗漏等号        {            iSum += aTarget[iOffset];        }        if (iSum > iSumMaxLeft)//如果新的和大,更新左侧最大的子数组元素之和iSumMaxLeft以及此时子数组起始下标iOffsetMaxLeft        {            iSumMaxLeft = iSum;            iOffsetMaxLeft = iOffsetLeft;        }    }/* 正向扫描包含iOffsetMid元素右侧的最大子数组 */    for (; iOffsetRight <= iOffsetEnd; iOffsetRight++)    {        iSum = 0;        for (iOffset = iOffsetMid; iOffset <= iOffsetRight; iOffset++)//求取数组从下标iOffsetMid到iOffsetRight的元素总和,注意:请勿遗漏等号        {            iSum += aTarget[iOffset];        }        if (iSum > iSumMaxRight)//如果新的和大,更新右侧最大的子数组元素之和iSumMaxRight以及此时子数组起始下标iOffsetMaxRight        {            iSumMaxRight = iSum;            iOffsetMaxRight = iOffsetRight;        }    }    /* 输出结果 */    msaAcrossMid.iSumMax = iSumMaxLeft + iSumMaxRight - aTarget[iOffsetMid];    msaAcrossMid.iOffsetMaxBegin = iOffsetMaxLeft;    msaAcrossMid.iOffsetMaxEnd = iOffsetMaxRight;    return(msaAcrossMid);}


0 0