数据结构(算法)总结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
多项式时间- 人们可以接受的时间复杂度(不会长到没尽头)。
P问题- 可以在多项式时间内解决的问题。
NP问题- 可以猜到答案,并可在多项式时间内验证是否正确的问题。
NPC(完全)问题- 是NP问题,且其它所有NP问题都可约化到它的问题。
NP-Hard(难)问题- 不一定是NP问题,但其它所有NP问题都可约化到它的问题。
时间复杂度的概念:
给定算法的运行时间增长趋势,一般输入规模看成很大。
(渐进)阶从低到高:
1 < log n < n < nlog n < n
2 < n
3 < 2n < n! < n n
「大O阶表示法」的计算原则:保留最高阶,去头去尾。
头:最高阶项的系数。
尾:非最高阶项与常数。
比如:
6n3 + 4n2 + 10000 = O( n3 )
10n2 + 2n = O(2n)
随机化算法分类:
数值随机化算法
舍伍德算法
拉斯维加斯算法
蒙特卡罗算法
棋盘覆盖(分治策略):
前提:棋盘必须正好有2k×2k(k = 自然数)个格子。
步骤:
1、将棋盘划分成4个子棋盘。
2、除了有特殊格的子棋盘外,其它3个盘里各取离结合点最近的格子,组成骨牌。
3、将每个子棋盘再划分成4个子棋盘,同样执行步骤2。
4、递归终止条件:子棋盘的普通格只剩3个。
比如一个8×8的棋盘(书p21页例子):
划为4等份:
不看有特殊格那份,其它3份取离结合点最近的格子,拉黑,就形成了一块骨牌。
现在每份都有1块特殊格,然后每份再划4等份:
每一小份重新执行上面的算法(递归了),忽视特殊份,拉黑离结合点近的。
然后继续递归,重复刚才的步骤(子问题结构完全相同)。
当然这里棋盘比较小,到这里已经可以看出结果。
递归中止条件:当子棋盘(划出的小份)只剩下3个普通格时。
七种常用排序算法的时间复杂度:
其中最坏情况最重要。
稳定性的意思:
假设有一个数组{ 2, 5, 2, 7, 1 }
其中第一个2假设叫a元素,第二个2叫b元素吧。
对其排序后得{ 1, 2, 2, 5, 7 }
原本a在b前面,如果排序后,a还在b前面,就是稳定的。它们调换了就是不稳定的。
也就是说稳定性,决定了同值元素的顺序会不会变动。
理论上,希尔和堆排序不会考,因为上课没讲过。
0-1背包(动态规划):
假设有3个物品:
物品A重3斤,价值4元;
物品A重4斤,价值5元;
物品A重5斤,价值6元。
考虑方式:
当放了n-1个物品时,第n个物品放还是不放?
设:
C - 当前背包容量(斤)
w[n] - 第n个物品的重量(斤)
v[n] - 第n个物品的价值(元)。
F( n, C ) - 将前n个物品放入容量为C的背包时,能获取的总价值。
如果不放第n个物品:
公式:F( n-1, C )
如果放第n个物品
公式:F( n-1, C - w[n] ) + v[n]
简单来说,就是把C、w[n]、v[n] 代入公式,看2个公式哪个得出的结果大,就选哪个。
然后可以构造出一张表:
解释下,X表示放不下,因为这里最轻的物品也要3斤,C=1或2时肯定放不下。
关键是后面绿色的值是怎么得到的,它是一行行构造出来的。
A行表示只有物品A时,怎么放能得到最大价值。
A + B行表示只有A与B时,怎么放能得到最大价值。
A +
B + C行表示有ABC时,怎么放能得到最大价值。
先看A行,因为就物品A,也没有什么比较公式,很显然C大于3时就可以放进A,因为每种物品就一个,所以不管背包多大,最大价值都是4元。
再看A + B行,从这行开始可以套公式了。
比如C=3时:
F( n-1, C ):就是A行C=3时的价值,也就是4元。
F( n-1, C - w[n] ) + v[n]:C-w[n] = 3 - 4 = -1 ,显然4斤的B根本放不进3斤的包。
所以最大价值是4元
再比如C=8时,
F( n-1, C ):还是4元。
F( n-1, C-w[n] ) + v[n]:C-w[n] = 8 - 4 = 4,F( n-1, 4 ),也就是A行的C=4,为4,再加上v[n]=5,最终结果是9元。
最大价值选大的,9元。
再看A + B + C行,一样的,就举C=9时的例子吧:
F( n-1, C ):A + B放在C=9,查表得9元。
F( n-1, C-w[n] ) + v[n]:F( A+B, 9-5 ) + 6 = 11元。
选大的,11元。
最终整表的右下角那个,就是整道题的最优解,即11元。
所谓动态规划,就是在算法中,逐步建立起这张表。填表过程中,后面的值可能会依赖前面的值,这时只要去查表就行了,而不用去临时计算。换言之,不做重复的子计算。这种算法效率高了,但存表需要空间,典型的空间换时间的做法。
矩阵连乘(动态规划):
矩阵连乘怎么算不重要,这里不写了。
关键3点:
1、相乘的矩阵,前面一个的列数要与后面一个的行数相等。
比如3行5列与5行2列的可以乘。
而3行5列与4行2列的没法乘。
2、a行b列与b行c列相乘,会得到一个a行c列的矩阵。
3、a行b列与b行c列相乘,元素相乘次数= a×b×c(次)。
换言之,假设有不同的矩阵A、B、C。
那么(A×B)×C与A×(B×C),会产生不同的相乘次数。
而这个问题就是要找到,相乘次数最少的顺序。
举例来说,约定A(3, 5)表示一个3行5列的矩阵,假设有:
A(3, 5)
B(5, 4)
C(4, 7)
如果按(A×B)×C的顺序:
A×B = (3, 4),相乘次数= 3×5×4 = 60
( 3, 4 )×C,相乘次数= 3×4×7 = 84
最终,整个连乘过程中,次数为60+84 = 144(次)
如果按A×(B×C)的顺序:
B×C = (5, 7),相乘次数= 5×4×7 = 120
A×( 5, 7 )×C,相乘次数= 3×5×7 = 105
最终,整个连乘过程中,次数为120+105 = 225(次)
显然第一种乘得少,乘得少代表效率高,这就是我们追求的。
算法执行过程中,也会逐步建立2张表(书上p48的(b)和(c)表)按书上的例子,有6个矩阵A1~A6,最终填表得:
断开位置表: