《算法导论》——MaximumSubArray
今天我们讨论的算法是最大子数组问题。
首先我定义了一个类用来保存最大子数组的开始位置索引、结束位置索引和该数组的和。代码如下:
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的更多相关文章
- B树——算法导论(25)
B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...
- 红黑树——算法导论(15)
1. 什么是红黑树 (1) 简介 上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...
- 基本数据结构(2)——算法导论(12)
1. 引言 这一篇博文主要介绍链表(linked list),指针和对象的实现,以及有根树的表示. 2. 链表(linked list) (1) 链表介绍 我们在上一篇中提过,栈与队 ...
- 堆排序与优先队列——算法导论(7)
1. 预备知识 (1) 基本概念 如图,(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树.树中的每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且从左向右填充.堆的数组 ...
- quickSort算法导论版实现
本文主要实践一下算法导论上的快排算法,活动活动. 伪代码图来源于 http://www.cnblogs.com/dongkuo/p/4827281.html // imp the quicksort ...
- [算法导论]二叉查找树的实现 @ Python
<算法导论>第三版的BST(二叉查找树)的实现: class Tree: def __init__(self): self.root = None # Definition for a b ...
- 算法导论第十八章 B树
一.高级数据结构 本章以后到第21章(并查集)隶属于高级数据结构的内容.前面还留了两章:贪心算法和摊还分析,打算后面再来补充.之前的章节讨论的支持动态数据集上的操作,如查找.插入.删除等都是基于简单的 ...
- 算法导论----VLSI芯片测试; n个手机中过半是好的,找出哪些是好手机
对于分治(Divide and Conquer)的题目,最重要是 1.如何将原问题分解为若干个子问题, 2.子问题中是所有的都需要求解,还是选择一部分子问题即可. 还有一点其实非常关键,但是往往会被忽 ...
- [置顶] 《算法导论》习题解答搬运&&学习笔记 索引目录
开始学习<算法导论>了,虽然是本大部头,可能很难一下子看完,我还是会慢慢地研究的. 课后的习题和思考有些是很有挑战性的题目,我等蒻菜很难独立解决. 然后发现了Google上有挺全的algo ...
- (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)
(搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...
随机推荐
- xe5 android 控制蓝牙[转]
用以下代码中的接口实现控制蓝牙的开.关及详细信息 unit Androidapi.JNI.BluetoothAdapter; // (c) RedTitan Technology 2013// JNI ...
- selenium phantomjs 设置代理ip方法
最近遇到phantomjs动态更换ip的功能,在知乎上看到一篇不错的文章,顺手记下来以备后用 phantomjs selenium 如何动态修改代理? 可以这样做(Python代码): # 不使用代理 ...
- php 直接获取url参数赋值成变量。省去繁琐的获取参数,再一个个赋值
php 直接获取url参数赋值成变量.省去繁琐的获取参数,再一个个赋值 parse_url() 该函数可以解析 URL,返回其组成部分.它的用法如下: array parse_url(string $ ...
- 自定义指令 格式化input数据为非负整数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- C++中函数的形参为数组时,实质形参是指针
C++中函数的形参如果为数组的话,那么进行实参传递时,实参实际上换转化成指针.参考下面的例子: #include<iostream> using namespace std; void f ...
- 流媒体技术笔记(DarwinStreamingServer相关)
简介 Darwin Streaming Server简称DSS.DSS是Apple公司提供的开源实时流媒体播放服务器程序.整个程序使用C++编写,在设计上遵循高性能,简单,模块化等程序设计原则,务求做 ...
- MyBatis 对数据库进行CRUD操作
1.update修改 uodate修改也可以使用之前的机制在配置文件中直接编写sql 但是update语句的set字句中是根据传入的值决定的, 此时可以通过Mybatis提供的标签实现判断动态拼接up ...
- [UE4]name slot一个种应用技巧
如图所示“MouseOver”是一个Child Widget,是一个按钮. “Image_0”跟“MouseOver”是重叠在一起的,这样“Image_0”就会挡住“MouseOver”按钮的事件响应 ...
- [UE4]利用取模运算达到循环遍历数组的目的
X mod Y: 1.X<Y: X mod Y = X.计算记过永远都是等于X 2.X=Y:X mod Y = 0.重新回到数组第一个索引位置
- python中文件操作
打印进度条