标签:第二章 函数 大话 算法 时间 常数 数据结构 复杂度 输入
第二章 算法
2.1 开场白
2.2 数据结构与算法关系
2.3 两种算法的比较
#include <iostream>
using namespace std;
int method1()
{
int i, sum = 0, n = 100;
for (i = 1; i <= n; i++)
{
sum = sum + i;
}
cout << sum;
}
int method2()
{
int i, sum = 0, n = 100;
sum = (1 + n) * n / 2;
cout << sum;
}
2.4 算法定义
算法:是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
2.5 算法的特性
(1)输入输出:算法具有零个或多个输入。算法至少有一个输出。
(2)有穷性:指算法在执行有限的步骤后,自动结束而不会出现无线循环,并且每一个步骤都是在可接受的时间内完成。
(3)确定性:算法的每一个步骤都具有确定的含义,不会出现二义性。
(4)可行性:算法的每一步都必须是可行的,也就是说,每一步都能够通过有限次数完成。
2.6 算法设计的要求
(1)正确性:
-
算法程序没有语法错误
-
算法程序对于合法的输入数据能够产生满足要求的输出结果
-
算法程序对于非法的输入数据能够得出满足规格说明的输出结果。
-
算法程序对于精心选择的,甚至刁难的测试数据都有满足要求的输出结果
本书将第三层次作为一个算法是否正确的标准。(写算法时至少要特别注意一些特殊边界的处理,尽量多考虑一些特殊情况)
(2)可读性
(3)健壮性:当输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的结果。
(4)时间效率高和存储量低
2.7 算法效率的度量方法
(1)事后统计法:拿同一套测试数据去测试不同的算法,通过比较运行时间来确定算法效率的高低。存在各种问题:浪费时间精力、环境依赖高、测试数据设计困难。
(2)事前分析估计方法
一个高级程序语言编写的程序在在计算中运行消耗的时间取决于以下因素:
-
算法采用的策略和方法(算法好坏的根本)
-
编译产生的代码质量(由软件来支持)(所谓JVM的优化是不是就是在优化这部分内容?)
-
问题的输入规模
-
机器执行指令的速度(由计算机硬件决定)
如对于以下三种算法,其输入规模都是n = 100。第一种算法执行了 2n + 3 次,第二种算法执行了3次,第三种算法执行了n²次(忽略循环体头尾的开销)。
int method3()
{
int i, sum = 0, n = 100; // 执行一次
for (i = 1; i <= n; i++) // 执行了n+1次
{
sum = sum + i; // 执行了n次
}
cout << sum; // 执行了1次
}
int method4()
{
int i, sum = 0, n = 100; // 执行了1次
sum = (1 + n) * n / 2; // 执行了1次
cout << sum; // 执行了1次
}
int method5()
{
int i, j, x = 0, sum = 0, n = 100; // 执行了1次
for (i = 1; i <= n; i++)
{
for (j = 1; i <= n; i++)
{
x++; // 执行了n*n次
sum += x;
}
}
cout << sum; // 执行了1次
}
如果仅考虑算法基本操作的数量,忽略循环体、初始化等其他不重要操作,对于同样输入规模n,第一段代码的操作次数f(n) = n,而第二种f(n) = 1,第三种f(n) = n²。因此,重要的是把基本操作数量和输入规模关联起来,即基本操作的数量必须表示为输入规模的函数。如下图。
2.8 函数的渐进增长
f(n) = 2n + 3 和 f(n) = 3n + 1 两个算法哪个更好呢?答案:总体上来说前者更好。
函数的渐进增长:给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的 n > N,f(n)总是比g(n)大,那么我们说f(n)的增长渐进快于g(n)。
比较函数之间的渐进增长时,通常忽略常数的加减法,通常忽略与最高次项相乘的常数,最高次项的指数越大,随着n的增加,函数增长得越快。因此判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数。
2.9 算法时间复杂度
(1)算法时间复杂度定义:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间度量,记作:T(n) = O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。(类似于数学中的同阶无穷小,比较的都是增长速度。)
一般情况下,随着n的增大,T(n)增长最慢的算法为最优算法。
非官方名称:O(1) —> 常数阶;O(n) —> 线性阶;O(n²) —> 平方阶;O(log n) —> 对数阶
(2)推导大O阶方法
-
用常数1取代运行时间中的所有加法常数
-
在修改后的运行次数函数中,只保留最高阶项
-
如果最高阶项存在且不是1,则去掉与最高阶项相乘的常数
因此,算出一个算法的时间复杂度为O(3)是错误的,因为并没有O(3)这种说法,而是O(1)。具体举例见原书。
2.10 常见的时间复杂度
2.11 最坏情况和平均情况
(1)最坏情况:是一种时间保证,那就是保证算法运行时间不可能比这更长。
(2)平均情况:是指所有情况中最有意义的,因为它是期望的运行时间。
一般在没有特殊说明的情况下,算法时间复杂度都是指最坏时间复杂度。
2.12 算法空间复杂度
算法空间复杂度定义:是指计算算法所需的存储空间,计算公式记作:S(n) = O(f(n)),其中 n 为输入规模,f(n)为语句关于n所占存储空间的函数。
标签:第二章,函数,大话,算法,时间,常数,数据结构,复杂度,输入 来源: https://www.cnblogs.com/yuyr757/p/13882359.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。