数据结果与算法分析(1)——算法分析
在确定一个算法正确的同时,也要保证算法的有效性。算法分析的最重要的标准时运行时间T(N),运行时间与输入元素个数N有关。
数学基础
T(N) = O(f(N)) 表示T(N)以不快于f(N)的速度增长,也就是说,f(N)是T(N)的上界。f(N) = Ω(T(N)) 表示T(N)是f(N)的下届。
例:N3增长快于N2,因此N2 = O(N3) 或 N3 =Ω(N2)
法则:
- 若T1(N) = O(f(N))且T2(N) = O(g(N)),则有(a) T1(N)+ T2(N) = max{ O(f(N)) , O(g(N)) };(b) T1(N)* T2(N) =O( f(N * g(N) ).
- 如T(N)是k次多项式,则T(N) = theta( Nk )
- logkN = O(N)
大O中不包含常数项和低阶项。
算法运行时间
算法估计的运行时间一般是最坏运行时间。运行时间计算的一般法则:
- for循环:至多是for循环的语句(包括测试)的运行时间乘以迭代次数。
- 嵌套for循环:嵌套内的一条语句的运行时间是该语句运行时间乘以所有外层for循环大小的乘积。
- 顺序语句:所有语句中运行时间的最大值。
- if S1 else S2:至多为判断加上max(S1,S2)。
算法举例 (1)最大序列和问题
最大序列和问题的求解给出了四种解法,其中前两种解法是最常规的遍历所有的子序列和,这样的方法运行时间比较大,分别为O(N3)和O(N2),对于这两种方法这里不详细叙述,重点叙述采用所谓“分治策略”的算法以及一个十分巧妙的算法。
解一:
将整个序列划分成三个部分,左半部分、右半部分以及跨越中部包含左右的中间部分。那么子序列和的最大值就只能出现在这三个位置。这样就可以以递归的方式求得左右部分的最大子序列和,然后将二者结合求出中间部分(包含左半部分的最后一个元素和右半部分的第一个元素)的最大子序列和。这个算法的时间复杂度为O(N logN)算法代码如下。
- static int
- MaxSubSum(const int A[], int left, int right)
- {
- int MaxLeftSum, MaxRightSum;
- int MaxLeftBorderSum, MaxRightBorderSum;
- int LeftBorderSum, RightBorderSum;
- int center, i;
- if(left == right)
- {
- if(A[left] > 0)
- return A[left];
- else
- return 0;
- }
- center = (left + right) / 2;
- MaxLeftSum = MaxSubSum(A, left, center);
- MaxRightSum = MaxSubSum(A, center + 1, right);
- MaxLeftBorderSum = 0; LeftBorderSum = 0;
- for(i = center; i >= left; i --)
- {
- LeftBorderSum += A[i];
- if(LeftBorderSum > MaxLeftBorderSum)
- MaxLeftBorderSum = LeftBorderSum;
- }
- MaxRightBorderSum = 0; RightBorderSum = 0;
- for(i = center + 1; i <= right; i ++)
- {
- RightBorderSum += A[i];
- if(RightBorderSum > MaxRightBorderSum)
- MaxRightBorderSum = RightBorderSum;
- }
- return Max( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
- }
- int
- MaxSubsequenceSum(const int A[], int N)
- {
- return MaxSubSum(A, 0, N-1);
- }
解二:
这种解法可以被叫做扫描法,因为它只需要对数据进行一次扫描,一旦A[i]被读入处理,A[i]就不需要被记忆了,算法能对它已经读入的数据给出正确答案,这样的算法也叫做联机算法(online algorithm)。现在来解释这一个算法的运行过程,对于一个数列中的元素,依次读入数组的元素并求和,每次求和之后与之前获得的最大和比较,若比之大则更新最大和,若比之小则不更新,若小于0,则令为0(题设:若数据全为负,则输出为0)。如果前k个数的和为负,那么这个和与之后的元素的和不会大于这个元素本身,因此将有负数的和令为0是可行的。
下面先给出这种算法的代码表示。
- int
- MaxSubsequenceSum(const in A[], int N)
- {
- int ThisSum, MaxSum, j;
- ThisSum = MaxSum = 0;
- for(j = 0; j < N; j++)
- {
- ThisSum += A[j];
- if(ThisSum > MaxSum)
- MaxSum = ThisSum;
- else if(ThisSum < 0)
- ThisSum = 0;
- }
- return MaxSum;
- }
算法举例 (2)对分查找
对分查找:给定一个整数X和整数A0,A1…….An-1,后者已排序,求X在A中的下标,若不在数据中返回-1。
对分查找的基本思想是,用X与中间元素对比,如相等则可返回,若X比中间元素大,则继续在后半部分(假设升序)递归查找,反之在前半部分递归查找。算法如下:
- int
- BinarySearch(const ElementType A[], ElementType X, int N)
- {
- int left, right, mid;
- left = 0; right = N - 1;
- mid = (left + right) / 2;
- while(left <= right) //查找是否结束
- {
- if(X == A[mid])
- return mid;
- else if(X > A[mid])
- left = mid + 1;
- else
- right = mid - 1;
- }
- return -1;
- }
算法举例 (3)欧几里得算法
欧几里得算法是用来计算最大公因数的。从下面的算法描述中可以看出,这个算法非常精妙,而且复杂度为O(logN)。欧几里得算法依赖一个定理
gcd(a,b) = gcd(b,a mod b) (a>b 且a mod b 不为0)
实际上,在算法中如果N>M时,循环的第一次迭代将使他们互换。
- unsigned int Gcd(unsigned int M, unsigned int N)
- {
- unsigned int Rem;
- while(N > 0)
- {
- Rem = M % N;
- M = N;
- N = Rem;
- }
- return M;
- }
算法举例 (4)高效率求幂运算
常规的XN求幂运算方法是对X进行N-1此自乘,其复杂度为O(N),可以想象,在N很大的时候其消耗还是很惊人的。因为XN=XN/2*XN/2,于是有下面递归实现的高效率求幂运算。由于把一个求幂运算分成两个最多只需要两次乘法(N为奇数时),所以乘法总次数最多为2logN.
- long int //long int防止过大的数溢出
- Pow(long int X, unsigned int N)
- {
- if(N == 0)
- return 1;
- if(N == 1)
- return X;
- if(N % 2 == 0)
- return Pow(X*X, N/2);
- else
- return Pow(X*X, N/2) * X;
- }
数据结果与算法分析(1)——算法分析的更多相关文章
- C语言学习书籍推荐《数据结构与算法分析:C语言描述(原书第2版)》下载
维斯 (作者), 冯舜玺 (译者) <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行 ...
- 《数据结构与算法分析-Java语言描述》 分享下载
书籍信息 书名:<数据结构与算法分析-Java语言描述> 原作名:Data Structures and Algorithm Analysis in Java 作者: 韦斯 (Mark A ...
- RapidMiner的基本使用(一个医疗数据的简单决策树算法分析)
RapidMiner的基本使用(一个医疗数据的简单决策树算法分析) RapidMiner的基本使用(一个医疗数据的简单决策树算法分析) 需要分析的文件: 右键分别创建读取excel数据,选择属性,设置 ...
- 某某水表-M1卡数据算法分析
# 某某水表-M1卡数据算法分析 ## 卡片数据-----------------------------扇区数据 | 金额:--- |:---13EC 0000 0000 0000 0000 000 ...
- 【算法杂谈】Miller-Rabin素性测试算法
额,我们今天来讲一讲Miller-Rabin素性测试算法. 读者:怎么又是随机算法!!!(⊙o⊙)… [好了,言归正传] [费马小定理] 费马小定理只是个必要条件,符合费马小定理而非素数的数叫做Car ...
- BZOJ 1029: [JSOI2007]建筑抢修 贪心
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1029 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落 ...
- TCP/IP详细解释--TCP/IP可靠的原则 推拉窗 拥塞窗口
TCP和UDP在同一水平---传输层.但TCP和UDP最不一样的地方.TCP它提供了一个可靠的数据传输服务,TCP是面向连接的,那.使用TCP两台主机通过第一通信"拨打电话"这个过 ...
- TCP/IP详细说明--滑模、拥塞窗口、慢启动、Negle算法
TCP的数据流大致能够分为两类,交互数据流与成块的数据流. 交互数据流就是发送控制命令的数据流.比方relogin,telnet.ftp命令等等.成块数据流是用来发送数据的包,网络上大部分的TCP包都 ...
- 洛谷P1048 采药
题目OJ地址 https://www.luogu.org/problemnew/show/P1048 https://vijos.org/p/1104 题目描述辰辰是个天资聪颖的孩子,他的梦想是成为世 ...
随机推荐
- HDU 4777 Rabbit Kingdom 树状数组
分析:找到每一个点的左边离他最近的不互质数,记录下标(L数组),右边一样如此(R数组),预处理 这个过程需要分解质因数O(n*sqrt(n)) 然后离线,按照区间右端点排序 然后扫一遍,对于当前拍好顺 ...
- [selenium webdriver Java]检查元素是否存在
Selenium WebDriver没有实现Selenium RC的isElementPresent()方法来检查页面上的元素是否存在. 在WebDriver中封装一个类似的方法,如下: public ...
- Java HashMap存储问题
public static boolean isIsomorphic(String s, String t) { Map map1 = new HashMap<>(); Map map2 ...
- vs 中代码的字体也颜色设置
使用vs之前,需要进行一些常规的配置,以便更加方便自己的使用提高工作效率.字体应该配置为Consolas等宽字体,另外项背景色应设置为自定义淡蓝色(84,91,205),一说这颜色能保护眼睛,确实看的 ...
- bzoj 1058 [ZJOI2007]报表统计(set)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1058 [题意] 一个序列,提供插入,查询相邻最小差值,查询任意最小差值的操作. [思路 ...
- position属性
所有主流浏览器支持position属性: 任何版本的ie浏览器都不支持属性值“inherit”. position属性规定元素的定位类型,任何元素都可以定位,不过绝对定位或固定元素会生成一个块级框,不 ...
- [转载] Zookeeper中的 ACL(Access Control List)访问控制列表
zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机制来解决访问权限问题,详见官网文档:ht ...
- 恒天云技术分享系列2 - vlan管理GUI开发
恒天云:http://www.hengtianyun.com/download-show-id-10.html 在OpenStack G版本中quantum网络模式下,horizon提供了基于quan ...
- 通过在shell脚本中用scp或rsync实现远程同步文件
通过在shell脚本中用expect实现远程scp文件 shell expect的简单用法 http://myunix.blog.51cto.com/191254/1095074 http://ji ...
- [iOS基础控件 - 6.2] LOL英雄列表 UITableView单项显示
A.需求 1.使用只有一个section的TableView来显示LOL 的英雄列表 2.内容包括标题.副标题.图标 3.使用plain样式 4.使用MVC模式 heros.plist 文件结 ...