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);
}