【读书笔记】Algorithm Design and Analysis

前言:
这是我的早期作品 当时所知甚少 刚开始会用python print.
因此 这篇文章只适合初学者,当然,也适合进阶者对算法知识的系统性回顾。重要的和常忘的在文中会重点标出来。
第五章 分治法
5.1,5.2 Merge sort and quick sort都属于分治法的实现。
其中,快速排序应用十分广泛,而且有许多改进版本,quick sort能解决的一个重要问题就是荷兰国旗问题,他要求对于R,W,B构成的任意数组变成严格的RWB顺序。
5.3 分治法在二叉树上的应用表现在其能在遍历二叉树时有不同的方法:
Preorder traversal : root->left->right
Inorder traversal : left->root->right
Postorder traversal : left->right->root
换句话说,前序中序后序遍历是相对于根节点的遍历顺序来说的。
需要注意的是,并不是所有关于二叉树的算法都是需要遍历左右两个树,比如,其查找,插入和删除操作只需要遍历两课子树中的一棵。
5.4 大整数乘法和strassen矩阵乘法
首先我们可以想一下,两个数的乘法应该如何计算?看起来是每个数的每一位都要和另一数的每一位相乘,所以看起来是需要n^2的复杂度。
但是实际上,我们可以采取这样的算法:对于任意的l两位数a,b我们有a=a1a0, b=b1b0,其乘积为:c=ab=a1b1102 +[(a1+a0)(b1+b0)-(a1b1+a0b0)]10^1+a0b0. 所以推广开来,如何跟分治法联系到一起呢?就是把任意的数都分成前后两部分,然后一直向下分,直到到最底层。
因此这张算法很有优势。其乘法次数的递推式为M(n) = 3M(n/2).
所以,既然分治法可以减少两个数乘法中的位乘次数,那么他同样可以在矩阵乘法中发挥作用,因为矩阵乘法的基础就是数乘。而且宏观来说,矩阵乘法也可以分治。以两个2 * 2的矩阵相乘为例,本来我们是需要八次乘法和四次加法,但是用了分治法就只需要7次乘法和18次加减法。想象一下每次都将任意矩阵进行2*2的分块。所以,strassen算法的时间复杂度是O(nlog7),要比蛮力法n3要好。事实上,一些其他算法比如【Coo87】,其时间效率被压缩到了n2.376.
当实际实现strassen算法的时候,当 矩阵的规模变得小于某转化点时,就切换到了蛮力法。
5.5 采用分治法解决最近对和凸包问题。解决最近对和凸包问题的蛮力法算法的时间效率分别是n2和n3,最近对问题是找出空间中距离最近的两个点。那么怎么用分治法解决呢?
简单的来说,我们可以把这些点按照x坐标进行升序排列,当点的数量大于3时,可以利用点集在x轴方向的中位数m,在该处做一条垂线,将点集分成大小为n/2的两个子集然后可以通过求递归来即求解子问题来得到最近点对问题的解。

第六章 变治法
什么是变治思想呢? 有三种主要的类型:
变换为同样问题的一个更简单或者更方便的实例/变换为同样实例的不同表现/变换为另一个已知算法问题的实例。
感觉以上的东西都过于抽象…
6.1 预排序(LC题目中经常用到 主要就是看题目是否允许原顺序变化或者sort之后是否使得问题更加简单)
需要指出的是,预排序并不是一种排序方法,而是说在对某一可排序列表进行操作前,提前对其进行排序对性能的影响。以下面三个例子为例:
检验数组中元素的唯一性:之前考虑过蛮力算法,就是对数组中的所有元素进行比较,直到所有的元素已经比较完毕,或者找到了两个相等的元素。如果我们换一种做法,先对数组进行排序,只检查她的连续元素,如果有相等的元素,那么一定有一对元素是互相紧挨着的,反之亦然。
其他两个问题是模式问题和查找问题,总结性的来说,如果我们采用排完序之后的数组进行处理我们的问题 比 不排序而直接处理我们的问题 效率要高的话,预排序处理就是值得的。
6.2 高斯消去法
即在解Ax = b的时候,我们知道A如果为上三角的话会非常好求,所以我们就通过GE将A变为这样的上三角阵。有向前消去法和向后消去法,为了防止可能的break down,我们还采用的partial pivoting的方式,此算法的效率是立方级的。
高斯消去法有一个有趣也非常有用的副产品,被称为系数矩阵的LU分解。而且高斯消去法本来是用来解线性方程组的,现在也可以用来求矩阵的逆/行列式。
6.3 平衡查找树
我们之前讨论过二叉查找树,他是一种实现字典的重要的数据结构。二叉树节点所包含的元素来自可排序项的集合,每个节点一个元素。请注意,把一个集合变化为一棵二叉查找树,是 变治法 的一个实例。这种变换的实现,能给我们带来什么好处呢?我们之前通过二叉查找树赢得了logn的插入查找删除的时间效率。但是这仅仅在平均情况下成立,在最差情况下,这些操作属于n,因为这种数可能退化成一种严重不平衡的树。
那么我们要怎么样做可以既能保留二叉查找树的好特性,又能避免其退化到最差情况的数据结构。
目前我们有两套方案,第一套是 讲义和不平衡的二叉查找树转变为平衡的方式,这个思想的特定实现之间的区别是他们对所谓的平衡的定义是不同的。因此我们的两种方法分别为 AVL树和红黑树。AVL树要求他的每个节点的左右子树的高度差最多为1.红黑树能够最多允许同一节点的一棵子树的高度是另一棵子树的两倍。可是如果因为某一节点的插入或者删除产生了违背平衡要求的树会怎么样?那么我们就从一系列被称为旋转的特定变换中选择一种,重新构造这个树,使之满足平衡要求。
第二套是 他允许一颗查找树的单个节点中不止包含一个元素。比如说2-3树,2-3-4树以及B树。其区别在于单个的节点中能容纳的元素个数。
下面分别讨论AVL树和2-3树
AVL树:首先,什么是AVL树呢?他就是一棵二叉查找树,其中每个节点的平衡因子定义为其左子树和右子树的高度差(注意不是左子节点和右子节点的高度差欧),而只有当高度差最多为正负1的时候,才叫AVL树,如果大于1,说明不平衡的厉害,所以要采用旋转对此树进行调整。下面介绍4种最简单的旋转方式:右单转,左单转,左右双转,右左双转。注意,旋转的目的就是对平衡进行调整,同时调整之后必须要满足根节点大于左节点小于右节点。
值得注意的是:最差情况下,查找和插入删除操作的效率都是对数级的。但是这样好的效率也有代价,就是需要频繁的转换,维护节点的平衡。
2-3树:
什么是2-3树呢?他是一种包含两个类型节点的树2节点和3节点。2节点是只包含一个键K和两个子女,左子女作为一棵所有键都小于K的子树的根,右子女作为所有键值都大于K的根。3节点的根节点包含两个有序的键K1K2并且有三个子女,最左边只包含小于K1的节点,然后其他的你也能想象的出来。2-3树的最后一个要求是,树中所有的叶子必须位于同一层,ie,2-3树总是高度平衡的。为了这个特性,我们付出了每个节点拥有不止一个键的代价。
在2-3树中查找和插入一个键有些复杂,但是要明白路径和原理。和AVL一样,在最差和平均时间效率下,查找 插入 删除的时间效率都属于对数级。2-3树的一种重要的一般性形式是B树,将之后讨论。
6.4 堆和堆排序
什么是堆?通俗的定义:堆是一种灵巧的,部分有序的数据结构,他尤其适合实现优先队列。优先队列支持以下的操作:查找一个具有最高优先级的元素,删除一个具有最高优先级的元素,添加一个元素到集合之中。
堆的严格定义:他是一棵二叉树,树的每个节点中包含一个键,并且满足以下两个条件:必须是完全二叉树,只允许最后一层最右边可能有缺位。每一个节点的键都要大于等于他的子女的键(有些要求每个节点的键值小于等于其子女的键值,称之为最小堆。)
如何构造一个堆呢?有两种方法:自底向上堆构造和自顶向下堆构造。
那么什么是堆排序呢?这个算法是这样描述的:对给定要排序的数组进行堆构造操作,然后删除最大键,继续对剩下的应用n-1次根删除操作。堆排序的时间效率为nlogn,他需要先构造堆,然后再删除,构造堆的时间为O(n)。并且堆排序也不需要任何额外的空间。
6.5 霍纳法则和二进制幂
本节我们讨论两个问题:一个是已知x求x构成的多项式的结果问题。另一个是计算x的n次幂。
霍纳法则:这是一种计算多项式的方法。他是把每个x都提取出来,一层一层嵌套着乘下去。看上去真的很简单和智障…
二进制幂法看上去也不难,但是就是不太想看…所以先放一放8.
6.6 问题化简
就像解析几何的根本思想是将几何问题简化为代数问题一样,问题转化化简是一种重要的策略。
比如以下几个问题:
求最小公倍数:我们之前怎么求最小公倍数?先将数分解,然后挑出来相同的部分乘以不相同的部分。而我们之前也会求最大公约数。那么这个最小公倍数的问题就可能转化为最大公约数。而事实上他也能转化,即lcm = m*n/gcd.
计算图中的路径数量:即途中两个顶点之间可能的路径的数量问题。用数学归纳法可以证明,从图第i到第j顶点,长度为k的不同路径的数量等于A^k的(i,j )位置的元素。A是图的邻接矩阵表示法。
最优化问题:如果我们已知求一个函数最大值的算法,现在想求最小值,怎么办?此时就需要求负函数的最大值即可
线性规划:许多决策最优化问题都可以转化成线性规划的问题。我们可以试着将背包问题转化成线性规划问题(承重W的背包和n个重量为w1w2w3w4…,价值为v1v2v3v…的物品,如何实现价值最大化?这个就比较复杂了,但是仍然是一个很好的例子。(这是个整数线性规划的问题,难度系数十分高)
简化为图问题:可以将许多问题简化为一种标准图的问题。尤其是对于Puzzle和games来说,在这些应用中,图的顶点一般用来表示所讨论问题的可能的状态,边则表示这些状态之间的转变。

第七章 时空权衡(就是常说的trade off)
其基本思想为:对问题的部分或者全部输入做预处理,然后将获得的额外信息进行储存,以加速后面问题的求解。这个方法称为输入增强。有一些算法是以此为基础的:
计数排序,boyer-moore字符串匹配算法及其简化版本。
此外 预构造 方法也是基于此种思想,比如散列法和用B树做索引。
当然,最典型的还是 动态规划的以空间换时间。
值得注意的是,时间和空间并不是相对的概念,并不是一定是竞争关系。
7.1 计数排序
计数排序的思路是:他不是基于比较的排序,而且排序速度大于任何排序比较算法。其步骤大致如下:找出待排序数组中的最大和最小元素,统计数组中每个值为i的元素出现的次数,存入数组C的第i项。总而言之,计数记得是每个元素出现的次数。然后再将其还原为一个有序数组。就这样,得出最大值和最小值的时间复杂度是n,记录次数也需要遍历一遍因此复杂度也是N,而还原是不需要消耗时间的,所以总体是个线性复杂度。但是仔细想一下,如果遇到不是整数的排序怎么办?
7.2 字符串匹配中的输入增强技术:之前的蛮力算法就是采用指针,接下来讲的是利用了输入增强思想的其他更快速的算法。
第一种是Knuth-Morris-Pratt算法(从左向右比较)
第二种是Boyer-Moore算法(从右向左比较)
首先我们来看一个简化版本:Horspool算法
针对这三种算法 还是推荐看一下通俗易懂版本的吧
7.3 散列法
本节主要是讲在既然没有绝对完美的散列函数的前提下,我们应该怎么样处理碰撞的情况。
当然 我们其实之前已经知道了这两种方法利用散列链表和开放寻址两种方法。
7.4 B树
背景:如果所讨论的数据集合包含数量庞大的记录,那么利用额外的空间来提高给定数据集合访问的速度的思想就很重要了。而组织这种数据集合的一种主要技术是索引。索引对于结构化的记录(非 文本图像音频视频)的数据集合,这种很重要的数据结构叫B树,他对2-3树允许查找树的同一个节点包含多个键的思想进行了拓展。
之后详细的讲了 B树的组成以及其添加插入删除操作。这里具体就不细说了。因为过于复杂。

第八章 动态规划 DP
8.1 三个基本的例子
1 币值的最大化问题 给定一排n个硬币,面值为正整数,面值并不一定两两不同。请问如何选择硬币,使得其在原始位置并不相邻的条件下 所选硬币的总金额最大(?没看懂这个题是想干嘛)
2 找零问题 需要找零的金额为n,最少需要多少面值各不相同的硬币?
3 硬币收集问题 在n*m格木板中放入一些硬币,每格最多一个,在木板左上方有一个机器人需要尽可能收集更多的硬币并把其带到右下方的单元格,机器人只能右移或者下移一格。设计一个算法找出机器人能找到的最大硬币数并给出相应的路径
8.2 背包问题和记忆功能
动态规划方法所涉及的问题的解,满足一个用交叠的子问题来表示的递推关系。直接自顶向下对这样一个递推式求解导致一个算法要不止一次的解公共的子问题。因此效率较低。另一方面,经典的动态规划方法是自底向上工作的,它用所有子问题的解来填充表格,但是每个子问题只解一次。但是,在实际处理中,有时候求解每个子问题不是必须的。所以我们需要把自顶向下和自底向上的方法的优势结合起来,使得只对必要的子问题求解并且只解一次。所以我们引入了记忆化的功能。至于是什么 之后再看。
8.3 最优二叉查找树
什么叫最优二叉查找树?
普通的二叉查找树在进行查找的时候,需要多次进行键值对的比较。但是假如,通过历史数据统计得出集合中元素查找次数的概率。那么结合查找概率,使得成功查找的平均比较次数较少。
具体如何实现之后再研究。
8.4 warshall算法和floyd算法
这两个算法是干什么用的呢?第一个是用于计算有向图传递闭包,第二个算法是计算最短路径。本质上,这两种算法都是基于 目标问题和一个更简单的问题。因此具有DP特征。
8.4.1 Warshall算法
8.4.2 计算完全最短路径的Floyd算法 什么是完全最短路径的问题呢?给定一个加权连通图(有向或者无向)完全最短路径问题要求找到每个顶点到其他所有顶点之间的距离。他的解在通信交通运筹学上有重要的应用。
第八章总结:
动态规划方法是一种对具有交叠子问题的问题进行求解的技术,一般地说,这样的子问题出现在求解给定问题的递推关系之中。动态规划方法建议:与其对交叠问题的子问题进行一次又一次重复求解,不如对每个较小的子问题只解一次存在某个表中,用到的时候就直接取。

第九章 贪婪技术(贪婪算法)
当我们再次回到之前的硬币找零问题,对于某些实例来说的确是最优解,但是显然不是对所有的实例都有效。
贪婪法建议:通过一系列步骤来构造问题的解,每一步对目前构造的部分解做一个拓展,直到获得问题的完整解为止。他所做的选择的每一步都必须满足以下条件:
1 必须满足问题的约束
2 局部最优原理
3 不可取消。
下面讲几个基于此技术思想的算法:
9.1 Prim算法(构建MST的算法 即最小联通树)
这种算法是为了解决类似以下的问题:给定N个点,把他们按照一种代价最低的方式链接起来,使得任意两点之间都存在一条路径。这个问题的解应用广泛,可以用来寻找数据点集中的聚类,也可以用在学科的分类,或者有助于构造旅行商等难题的近似解。
如果用图中的顶点来表示上述问题的解,可能的连接用图的边来表示,连接成本用权重表示,那么上述问题可以表示成最小生成树问题。
下面定义来辅助理解:连通图的一棵生成树是包含图的所有顶点的联通无环子图。加权连通图的一棵最小生成树是图的一棵权重最小的生成树。所以最小生成树的问题就是求一个给定的加权连通图的最小生成树的问题

Harsh Bhasin, "Algorithms: Design and Analysis" English | ISBN: 0199456666 | 2015 | 692 pages Algorithms: Design and Analysis of is a textbook designed for the undergraduate and postgraduate students of computer science engineering, information technology, and computer applications. It helps the students to understand the fundamentals and applications of algorithms. The book has been divided into four sections: Algorithm Basics, Data Structures, Design Techniques and Advanced Topics. The first section explains the importance of algorithms, growth of functions, recursion and analysis of algorithms. The second section covers the data structures basics, trees, graphs, sorting in linear and quadratic time. Section three discusses the various design techniques namely, divide and conquer, greedy approach, dynamic approach, backtracking, branch and bound and randomized algorithms used for solving problems in separate chapters. The fourth section includes the advanced topics such as transform and conquer, decrease and conquer, number thoeretics, string matching, computational geometry, complexity classes, approximation algorithms, and parallel algorithms. Finally, the applications of algorithms in Machine Learning and Computational Biology areas are dealt with in the subsequent chapters. This section will be useful for those interested in advanced courses in algorithms. The book also has 10 appendixes which include topics like probability, matrix operations, Red-black tress, linear programming, DFT, scheduling, a reprise of sorting, searching and amortized analysis and problems based on writing algorithms. The concepts and algorithms in the book are explained with the help of examples which are solved using one or more methods for better understanding. The book includes variety of chapter-end pedagogical features such as point-wise summary, glossary, multiple choice questions with answers, review questions, application-based exercises to help readers test their understanding of the learnt concepts.
### 回答1: data structure and algorithm analysis in c是一本C语言数据结构和算法分析的经典教材,由Mark Allen Weiss编写。该书的主要特点是对数据结构和算法的讲解非常详细且透彻,采用了很多实例进行讲解,使得读者可以很快地掌握这些内容。此外,该书还特别强调了算法分析和设计的重要性,帮助读者理解复杂算法的实现方式,提高算法的优化能力。 而data structure and algorithm analysis in c的下载方式也非常简单,可以在网上找到相关的资源下载,并且也可以通过购买实体书的方式获得。对于想要深入学习C语言数据结构和算法分析的人来说,这本书是非常值得推荐的一本入门教材。 ### 回答2: data structure and algorithm analysis in c是一本关于C语言数据结构和算法分析的经典教科书。该书涵盖了广泛的数据结构和算法,包括数组、链表、树、图、排序、查找等。本书不仅涵盖了基本概念和技术,而且提供了深入的分析和高级应用。书中有丰富的例子和习题,方便读者深入理解和应用。该书是学习数据结构和算法的好材料,对于提高程序员的编程能力和解决问题的能力有很大的帮助。 ### 回答3: Data Structure and Algorithm Analysis in C是一本面向C++程序设计开发人员的算法和数据结构分析书籍。它涵盖了许多重要的算法和数据结构,如排序和搜索算法,二叉树,平衡树和图论等方面。本书旨在帮助读者深入了解算法和数据结构的基本知识,并提供了许多实用的示例和演练题来帮助读者巩固自己的知识。 本书包含了许多实际的示例和演练题,这些题目涵盖了从简单到复杂的各种情况,有助于读者更好地理解和应用所学知识。与此同时,这本书也提供了大量的编码和调试技巧,帮助读者编写出高效和可维护的代码。 总之,Data Structure and Algorithm Analysis in C是一本优秀的参考书,无论你是刚接触算法和数据结构或是已经具备一定的基础,它都可以提供丰富的知识和实践经验。如果你正在寻找一本深入了解算法和数据结构的书籍,那么它一定是首选之一。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值