今天我们讨论的算法是最大子数组问题。

  首先我定义了一个类用来保存最大子数组的开始位置索引、结束位置索引和该数组的和。代码如下:

class MaximumSubArray
{
private:
int begin; //开始位置索引
int end; //结束位置索引
int sum; //和
public:
void setBegin(int Begin)
{
begin=Begin;
}
void setEnd(int End)
{
end=End;
}
void setSum(int Sum)
{
sum=Sum;
} int getBegin()
{
return begin;
}
int getEnd()
{
return end;
}
int getSum()
{
return sum;
}
};

  该算法采用分治策略,我们先讨论最大子数组跨越中点位置的情况:

MaximumSubArray FindMaxCrossingSubArray(int *numArray,int low,int middle,int high)
{
MaximumSubArray max;
int leftsum=numArray[middle];
int maxleft=middle;
int sum=;
for(int i=middle;i>=low;i--)
{
sum+=numArray[i];
if(sum>=leftsum)
{
leftsum=sum;
maxleft=i;
}
}
int rightsum=numArray[middle+];
int maxright=middle+;
sum=;
for(int j=middle+;j<=high;j++)
{
sum+=numArray[j];
if(sum>=rightsum)
{
rightsum=sum;
maxright=j;
}
}
max.setBegin(maxleft);
max.setEnd(maxright);
max.setSum(leftsum+rightsum);
return max;
}

  接下来是二分法求最大子数组:

MaximumSubArray FindMaximumSubArray(int *numArray,const int low,const int high)
{
MaximumSubArray max;
if(high==low)
{
max.setBegin(low);
max.setEnd(high);
max.setSum(numArray[low]);
return max;
}
if(high-==low)
{
max.setBegin(high);
max.setEnd(high);
max.setSum(numArray[high]);
return max;
}
int middle=(low+high)/;
MaximumSubArray left=FindMaximumSubArray(numArray,low,middle);
MaximumSubArray right=FindMaximumSubArray(numArray,middle,high);
MaximumSubArray cross=FindMaxCrossingSubArray(numArray,low,middle,high);
if(left.getSum()>=right.getSum()&&left.getSum()>=cross.getSum())
max=left;
else if(right.getSum()>left.getSum()&&right.getSum()>=cross.getSum())
max=right;
else
max=cross;
return max;
}

注意:

  该书中的伪代码并没有以下这段

if(high-==low)
{
max.setBegin(high);
max.setEnd(high);
max.setSum(numArray[high]);
return max;
}

因为在算法递归到数组中只有两个元素的时候,算出的middle值和low值是一样的(& 索引为0和1的两个元素),所以,在high==low的时候去索引小的元素,在high-1=low的时候取索引大的元素,避免无限循环。

以上代码,请放到如下注释的位置,保存为SubArray.h

#include <stdlib.h>

namespace dksl
{
//
//
//
}

  下面是程序测试代码及运行结果:

#include "stdafx.h"
#include <iostream>
#include "SubArray.h" using namespace std;
using namespace dksl;
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {, -, -, , -, -, -, , , -, , -, -, , -, };
MaximumSubArray max=FindMaximumSubArray(a,,);
cout<<"begin:"<<max.getBegin()<<endl;
cout<<"end:"<<max.getEnd()<<endl;
cout<<"sum:"<<max.getSum()<<endl;
system("PAUSE");
return ;
}

该算法的时间复杂度为θ(nlogn)

《算法导论》——MaximumSubArray的更多相关文章

  1. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  2. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  3. 基本数据结构(2)——算法导论(12)

    1. 引言     这一篇博文主要介绍链表(linked list),指针和对象的实现,以及有根树的表示. 2. 链表(linked list) (1) 链表介绍      我们在上一篇中提过,栈与队 ...

  4. 堆排序与优先队列——算法导论(7)

    1. 预备知识 (1) 基本概念     如图,(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树.树中的每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且从左向右填充.堆的数组 ...

  5. quickSort算法导论版实现

    本文主要实践一下算法导论上的快排算法,活动活动. 伪代码图来源于 http://www.cnblogs.com/dongkuo/p/4827281.html // imp the quicksort ...

  6. [算法导论]二叉查找树的实现 @ Python

    <算法导论>第三版的BST(二叉查找树)的实现: class Tree: def __init__(self): self.root = None # Definition for a b ...

  7. 算法导论第十八章 B树

    一.高级数据结构 本章以后到第21章(并查集)隶属于高级数据结构的内容.前面还留了两章:贪心算法和摊还分析,打算后面再来补充.之前的章节讨论的支持动态数据集上的操作,如查找.插入.删除等都是基于简单的 ...

  8. 算法导论----VLSI芯片测试; n个手机中过半是好的,找出哪些是好手机

    对于分治(Divide and Conquer)的题目,最重要是 1.如何将原问题分解为若干个子问题, 2.子问题中是所有的都需要求解,还是选择一部分子问题即可. 还有一点其实非常关键,但是往往会被忽 ...

  9. [置顶] 《算法导论》习题解答搬运&&学习笔记 索引目录

    开始学习<算法导论>了,虽然是本大部头,可能很难一下子看完,我还是会慢慢地研究的. 课后的习题和思考有些是很有挑战性的题目,我等蒻菜很难独立解决. 然后发现了Google上有挺全的algo ...

  10. (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)

    (搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...

随机推荐

  1. How to set up github to work with Visual Studio 2013

    http://michaelcrump.net/setting-up-github-to-work-with-visual-studio-2013-step-by-step/ 1. Create gi ...

  2. phinx 使用指南

    一 使用 第一步 安装 composer require robmorgan/phinx第二步 初始化php vendor/robmorgan/phinx/bin/phinx init创建目录db/m ...

  3. IntelliJ IDEA Configuring projects

    https://www.jetbrains.com/help/idea/configuring-projects.html Configuring projects A project in Inte ...

  4. maven使用配置

    一.maven常用的命令 maven通过命令对工程进行编译.测试.打包.发布.运行(基本的顺序) mvn compile:编译 mvn clean:清理,将target下的class文件清理 mvn ...

  5. [蓝桥杯]ALGO-87.算法训练_字串统计

    问题描述 给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的. 输入格式 第一行一个 ...

  6. vue之v-on

    我们可以用 v-on 指令绑定一个事件监听器,通过它调用我们 Vue 实例中定义的方法: <!DOCTYPE html> <html lang="en"> ...

  7. centos6.5网络虚拟化技术

    一.配置KVM虚拟机NAT网络 1.创建脚本执行权限 下面是NAT启动脚本 # vi /etc/qemu-ifup-NAT 赋予权限 # chmod +x /etc/qemu-ifup-NAT 下载镜 ...

  8. 第一次软件工程作业——html制作一份简单的个人简历

    源码链接(码云):https://gitee.com/yongliuli/codes/eavjr7lxotb85s0icnq1z68 简历效果图展示: 代码展示: 添加背景音乐的方法: 在<he ...

  9. CVE-2017-8570漏洞利用

    CVE-2017-8570漏洞是一个逻辑漏洞,利用方法简单,影响范围广.由于该漏洞和三年前的SandWorm(沙虫)漏洞非常类似,因此我们称之为“沙虫”二代漏洞. 编号 CVE-2017-8570 影 ...

  10. [CVE-2014-8959] phpmyadmin任意文件包含漏洞分析

    0x01 漏洞描述 phpmyadmin是一款应用非常广泛的mysql数据库管理软件,基于PHP开发. 最新的CVE-2014-8959公告中,提到该程序多个版本存在任意文件包含漏洞,影响版本如下: ...