整理磁盘时发现考研408时自己的笔记
线性表是具有相同数据类型的n个数据元素的有限序列。 逻辑上,每个元素有且只有一个直接前驱,有且只有一个直接后继(表头表尾元素例外)
使用顺序存储的时候即为顺序表。 使用链式存储即为链表。
线性表的顺序存储又称为顺序表,是一组地址连续的存储单元。特点是表中元素的逻辑顺序与物理顺序相同。 PS:动态分配并不是链式存储,同样属于顺序存储结构,只是分配的空间大小可以在运行时决定。 最主要的特点是随机访问,而且逻辑上相邻的元素物理上也相邻,所以插入和删除操作需要移动大量的元素。
错题:线性表的顺序存储结构是一种顺序存取的存储结构。 这个是错误的,是随机存取的存储结构。顺序存取是一种读写方式,不是存储方式,有别于顺序存储。 PPS:表的元素从1开始计数,C中的数组从0开始计算。
题目: [2010真题]1. 设将n(n>1)个整数存放到1维数组R中。试设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(X0,X1,…,Xn-1)变换为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1)。要求: (1)给出算法的基本设计思想 (2)根据设计思想,采用C或C++或java语言描述算法,关键之处给出注释 (3)说明你所设计算法的时间复杂度和空间复杂度 [2011年真题]2.一个长度为L(L>=1)的升序序列S,处在L/2个位置的数被称为中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现在由两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。要求: (1)给出算法的基本思想 (2)根据设计思想,采用C或C++或java语言描述算法,关键之处给出注释 (3)说明你所设计算法的时间复杂度和空间复杂度
(1)给出算法的基本设计思想 (2)根据设计思想,采用C或C++或java语言描述算法,关键之处给出注释 (3)说明你所设计算法的时间复杂度和空间复杂度
注释有感: 读注释的效果应当同读伪代码的效果一样 如果代码的内容无法直观表述,就需要写注释。 题目答案: 1.(1)可以将这个问题看作是把数组ab转换成数组ba(a代表前p个元素,b代表数组余下的n-p个元素),先将a逆置得到a-1b,再将b逆置,最后将ab逆置。 如对abcdefgh左移3个单位 Reverse(0,p-1),得到cbadefgh
(3)上述三个Reverse的时间复杂度分别为O(p/2),O((n-p)/2)和O(n/2),故所设计的算法的时间复杂度是O(n),空间复杂度是O(1) 另外,可以使用大小为p的辅助数组,先将左边p个元素导入,再将n-p个元素左移,再放回去。时间复杂度O(n),空间复杂度O(p) 2.(1)算法的基本思想如下: 分别求两个序列的中位数a和b, 若a=b,则算法结束 若a<b,则舍弃A序列小的一半,B序列大的一半,要求两个序列舍弃的长度相等 若a>b,则舍弃A序列大的一半,B序列小的一半,要求两个序列舍弃的长度相等 在保留的升序序列中,重复上述过程直到只含一个元素,较小者即为所求的中位数 (2)代码:
(3)算法的时间复杂度为O(log2n),空间复杂度为O(1) 3.(1)给出算法的基本设计思想: 算法的策略是从前向后扫描数组元素,标记出一个可能成为主元素的元素Num。然后重新计数,确认Num是否是主元素。 算法分为以下两步: a.选取候选的主元素:依次扫描所给数组中的每个整数,将第一个遇到的整数Num保存到c中,记录Num的出现次数为1;若遇到的下一个整数仍等于Num,则计数加1,否则计数减1;当计数减到0时,将遇到的下一个整数保存到c中,计数重新记为1,开始新一轮计数,即从当前位置开始重复上述过程,直到扫描完全部数组元素。 b.判断c中元素是否是真正的主元素:再次扫描该数组,统计c中元素出现的次数,若大于n/2,则为主元素;否则,序列中不存在主元素。 (2)算法实现:
(3)实现程序的时间复杂度为O(n),空间复杂度为O(1) PS:对于统考算法题,去花费大量时间思考最优解法是得不偿失的。
通常使用头指针来标识一个单链表,第一个结点称为头结点。
插入、删除结点的时间为O(1)。(虽然查找依旧是O(n))
循环链表中最后一个结点的指针不是NULL而是指向头结点。
使用数组描述链式结构。
以next=-1作为结束,与动态链表相同,只是不用修改指针。
错题:1.单链表中,增加一个头结点的目的时为了方便运算的实现。主要好处是:第一,有头结点后,插入和删除数据元素的算法统一了,不再需要判断是否在第一个元素之前插入或删除第一个元素;第二,不论链表是否为空,其头指针是指向头结点的非空指针,链表的头指针不变,因此空表和非空表的处理也就统一了。 2.
编程题: [2009]1.已知一个带表头结点的单链表,结点结构为[data|link]。假设该链表只给出了头指针list,在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data域的值,并返回1,;否则,只返回0,请问: (1)描述该算法的基本设计思想 (2)描述算法的详细设计步骤 (3)根据设计思想和实现步骤,采用程序设计语言实现算法,关键之处请给出简要注释。
1.(1)程序设计基本思想如下: 问题的关键是设计一个尽可能高效的算法,通过链表的一遍遍历,找到倒数第k个结点的位置。算法的基本设计思想是:定义两个指针变量p和q,初始时均指向头结点的下一个结点(链表的第一个结点),p指针移动到第k个结点时,q指针开始与p指针同步移动;当p指针移动到最后一个结点时,q指针所指示结点为倒数第k个结点。以上过程对链表仅进行一次扫描。 (2)算法的详细实现步骤如下:
栈:只允许一端进行插入和删除的线性表
队列是一种操作受限制的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。 操作特性是FIFO,故又称为先进先出的线性表。
分配一块连续的存储单元存放队列中的元素,并附设两个指针front和rear分别指示队头和队尾元素的位置。 队列的顺序存储类型描述
会出现假溢出,即data数组中仍然有存放元素的空间,但是仍然溢出了。
循环队列:将顺序队列看作是一个环状的空间 入队时少用一个队列单元
后者增设一个表示元素个数的数据成员,或者增设一个tag数据成员。
允许两端都可以进行入队和出队操作的队列
括号匹配 表达式求值(后缀) 递归 二叉树层次遍历
压缩存储:指为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间。其目的时为了节省存储空间 特殊矩阵:指具有许多相同矩阵元素或令元素,并且这些相同矩阵元素或零元素的分布有一定规律性的矩阵。常见的特殊矩阵有对称矩阵、上/下三角矩阵、对角矩阵等。
稀疏矩阵可以转为表,这时候会失去随机存储特性。
任何一棵非空树应该满足:
树中两个结点之间的路径是由两个结点之间所经过的结点序列构成的,而路径长度是路径上所经过边的个数。
层次遍历:需要使用队列,依次将孩子结点加入队列中
由二叉树的先序遍历和中序遍历可以唯一确定一棵二叉树。同理,二叉树的后序遍历和中序遍历也可以唯一确定一棵二叉树。 二叉树的层序序列和中序序列也可以确定一棵二叉树。只有先序序列+后序序列无法确定一棵二叉树。
线索二叉树的实质是对一个非线性结构进行线性化操作,使在这个访问序列中每一个结点都有一个直接前驱和直接后继。 引入线索二叉树的目的是加快查找结点前驱和后继的速度。 在二叉树线索化时,通常规定:若无左子树,令lchild指向其前驱结点;若无右子树,令rchild指向其后继结点。同时还需要增加两个标识域来表明当前指针域所指向的对象是指向左(右)子结点还是直接前驱(后继)
线索二叉树的存储结构:
以这种结点结构构成的二叉链表作为二叉树的存储结构,叫做线索链表。其中指向结点前驱和后继的指针,叫做线索。加上线索的二叉树叫做线索二叉树。对二叉树以某种次序遍历使其变为线索二叉树的过程叫做线索化。
线索二叉树的构造:对二叉树的线索化,实质上就是遍历一次二叉树,在遍历过程中检查当前结点左、右指针域是否为空,若为空,则将他们改为指向前驱或后继结点的线索。
算法题: [2014年]1.二叉树的带权路径长度(WPL)是二叉树中所有叶节点的带权路径长度之和,给定一棵二叉树T,采用二叉链表存储,结点结构为(left,weight,right)。其中叶节点的weight域保存该结点的非负权值。设root为指向T的根结点的指针,请设计求T的WPL的算法,要求: (1)给出算法的基本设计思想 a.基于先序递归遍历的算法思想使用一个static变量记录wpl,把每个结点的深度作为递归函数的一个参数传递,算法步骤如下:(标准答案如下,我个人更倾向于将wpl值作为函数返回值逐层返回)
(3)算法的代码如下 a. 基于先序遍历的算法
b.基于层次遍历的算法
c.非递归的后序遍历。非递归遍历都需要栈,而后序遍历需要额外保存信息
数的存储结构:可以使用顺序存储结构或链式存储结构
BST左子树非空,则左子树上所有点小于根节点的值;右子树非空,则右子树上所有点大于根节点的值。 查找、插入略 构造:依次输入数据元素,并将它们插入到二叉排序树上适当的位置。 删除(较复杂):删除结点必须维护二叉排序树的性质
显然,对于高度为H的二叉树,插入和删除的运行时间都是O(H),但如果二叉树在最坏的情况,会退化成链表,这时性能会指数增加。 二叉树上的查找与二分查找的性能接近。但是二分查找的判定树是唯一的,二叉排序树是不唯一的,相同的关键字其插入顺序不同可能生成不同的二叉排序树。
为了避免二叉树的高度增长过快,规定在插入和删除二叉树结点的时候,保证任意结点的左、右子树高度的绝对值差不超过1。 平衡因子=左子树高度-右子树高度,显然只能取-1、0、1.
平衡二叉树的插入:插入结点后,要检查其插入路径上的结点是否因为这次操作而导致了不平衡。每次调整的对象都是最小不平衡树,即在插入路径上离插入结点最近的平衡因子的绝对值大于1的结点作为根的子树
删除相同 查找为log2n
哈夫曼树的带权路径长度最小
前缀编码:如果没有一个编码是另外一个编码的前缀,则称这样的编码为前缀编码。
图G由顶点集V和边集E组成。|V|表示图G中顶点的个数,也称为图G的阶 表可以是空表,树可以是空树,但是图不可以是空图,即图中不能一个顶点都没有。图中至少要有一个点,但是边集可以为空。
当一个图为稀疏图时,使用邻接矩阵表示法显然要浪费大量的存储空间。图的邻接表法结合了顺序存储和链式存储方法。 顶点表:顶点域+边表头指针 边表:邻接点域+指针域
有向图的一种链式存储方式。在十字链表中,有向图的每一条弧有一个结点,对应于每个顶点也有一个结点
本质上还是邻接表,但是针对有向图寻找入弧作出了优化,因此很容易可以求得顶点的出度和入度。
邻接多重表是无向图的另一种链式存储结构 邻接表中难以求两个顶点之间是否存在边,以及难以执行删除边的操作。
PS:稀疏矩阵可以使用十字链表和三元组表进行压缩 补充:
BFS:分层遍历,借助辅助队列。 性能分析:空间复杂度O(|V|)(全部入队) 采用邻接表时,每个顶点入队一次,每条边至少访问一次,时间复杂度O(|V|+O|E|)。采用邻接矩阵时,查找每个顶点的邻接点所需时间为O(V),所以总的时间复杂度为O(|V|^2)
使用BFS可以求解非带权图的单源最短路 广度优先生成树对于邻接矩阵而言是唯一的,对于邻接表是不唯一的。
DFS 递归算法,需要借助递归工作栈,空间复杂度为O(|V|) 以邻接矩阵表示时,查找每个顶点的邻接点所需时间为O(|V|),故总的时间复杂度为O(|V|^2)。当以邻接表表示时,查找所有顶点的邻接点所需时间为O(|E|),访问顶点所需时间为O(|V|),总的时间复杂度为O(|V|+|E|) 基于邻接表的深度优先搜索树是不唯一的。
可以用图的遍历算法来判断图的连通性
一个连通图的最小生成树是图的极小连通子图,它包含图的所有顶点,且边的权值之和最小。 性质:
Dijkstra思路相同。思路如下:
显然,主要开销就是找dist的最小值,可以使用优先队列优化。 dijkstra是基于贪心策略的,在边上带有负权值的时候不适用(准确来说,是对于有负圈的图,dijkstra无法结束) 时间复杂度O(|V|^2)
时间复杂度O(|V|^3),但是很简单。 思路就是使用邻接矩阵来存储任意两个点之间的距离。对于任意两个点,枚举可能的中间结点并更新这个矩阵。
显然,如果图中存在环,则它不可能有拓扑序列。 如果一个点有多个直接后继,则拓扑排序的结果通常不唯一。
没错,和IT项目管理的关键路径法的那个关键路径是一个东西。 在带权有向图中,以顶点表示事件,有向边表示活动,边上的权值表示活动的开销,这样的网络称为AOE网。 AOE网的性质:
错题:MST的一个限制条件 当带权连通图中的任意一个环中所包含的边的权值均不相同时,其MST是唯一的。
顺序查找,即线性查找。一般分为对无序线性表的查找和按关键字有序的顺序表的顺序查找。
又称二分查找 算法如下:
又称索引顺序 查找,既有动态结构,又可以快速查找 基本思想:
设将长度为n的查找表分为b块,每块s个记录。 索引表中顺序查找的平均查找长度=(s^2+2s+n)/(2s) 索引表中二分查找的平均查找长度=ceil((log2(b+1)))+(s+1)/2
B树重点考察,B+树只考察基本概念 王道P263
B树,又称为多路平衡查找树,满足以下特性:
B树是所有结点的平衡因子均等于0的多路查找树 B树的大部分操作所需要的磁盘存取次数与B树的高度成正比。首先要明确,B树的高度不包括最下层叶节点所处的那一层。 对于任意一棵n个关键字,高度为h、阶数为m的B树
5.B+树 B树的一种变形树,m阶的B+树和m阶的B树区别:
在具体应用上,B+树比B树更适用于实际应用中的操作系统的文件索引和数据库索引,因为前者磁盘读写代价更低,查询效率更稳定。
以下用Hi表示第i次探测的散列地址
散列表的查找效率取决于三个因素:散列函数、处理冲突的方法和装填因子
串的模式匹配,就是求第一个字符串在第二个字符串中的位置
时间复杂度为O(nm),n、m分别为主串和模式串的长度
添加了失配函数,如果发生失配,并不直接归位,而是沿着next跳转。
我更喜欢算法导论版本的伪代码KMP
//匹配串T,模板串P
7.1 排序的基本概念
排序,就是重新排列表中的元素,使表中的元素按关键字递增或递减的过程。 算法稳定性:如果有两个元素Ri=Rj,其对应的关键字keyi=keyj,且排序时Ri在Rj的前面。如果使用某一排序算法排序后,Ri仍然在Rj前面,该算法是稳定的,否则称排序算法是不稳定的。
内部排序:指在排序期间元素全部存放在内存中的排序。
外部排序:指在排序期间元素无法全部同时存放在内存中,必须在排序的过程中根据要求不断地在内、外存之间移动的排序。
某一时刻状态:有序序列L[1…i-1]、L[i]、无序序列L[i+1…n] 为了将L[i]插入,执行以下操作:
查找出L[i]在有序序列的插入位置k
将L[k…i-1]的元素后移一个单位
稳定性:稳定的排序方法
实用性:适用于顺序存储和链式存储的线性表。 PS:大部分排序算法都仅适用于顺序存储的线性表。
查找有序子表的部分用折半查找来实现。在确定出待插入位置后,就可以统一地向后移动元素了。
直接插入排序适用于基本有序的算法和数据量不大的排序表,基于此提出了希尔排序,又称缩小增量排序。 基本思想:先将待排序表分割成若干个形如L[i,i+d,i+2d,…i+kd]的特殊子表,分别进行直接插入排序。党整个表中元素基本有序时,再对全体进行一次直接插入排序。 过程:
先取一个小于n的步长d1,把表中全部记录分成d1个组,所有距离为d1的倍数的记录放在同一个组中,同时在各组中进行直接插入排序;
然后取第二个步长d2<d1,重复该过程,直到所取到的d1=1,即所有记录已放到同一组中,再进行直接插入排序,由于此时已经具有较好的局部有序性,故很快可以得到结果。 PS:到目前为止,尚未求得最好的增量序列。希尔提出的办法是d1=n/2,di+1=floor(di/2),并且最后一个增量等于1. 如下:
1. 前后记录位置的增量是dk,不是1 2. r[0]只是暂存单元,不是哨兵,当j<=0时,插入位置已到
空间效率:仅使用了常数个辅助单元,因而空间复杂度为O(1)
时间效率:当n在某个特定范围内,约为O(n^1.3),在;最坏情况下希尔排序的时间复杂度为O(n^2)
实用性:仅适用于顺序存储
根据序列中两个关键字的比较结果来交换这两个记录在序列中的位置。重点考冒泡排序和快速排序,一般不会单独考察冒泡排序
基本思想:太简单,略。 每趟冒泡的结果都会将一个元素放在最终位置,比如用王道的算法,每次排序之后会将序列中最小的元素放在序列最前面。 记忆:想冒泡泡一样,每次从头撸到尾,最后一个就有序了,然后少撸一截。撸n-1遍。 冒泡有个很好的性质,就是如果撸一遍以后没有可以交换的对象了,那么之后也不再有可以交换的对象,可以提前结束算法。
//冒泡排序,从小到大 return;//本趟遍历后没有交换,说明序列已经有序
稳定性:稳定的 冒泡排序产生的有序子序列一定是全局有序的,即有序子序列中的所有元素的关键字一定小于无序子序列中的关键字(不同于直接插入排序)看,即到达最终位置。
基本思想是基于分治的。
//严谨的一趟排序过程
也有结合起来的版本,比如我NOIP时期的代码:
//记忆后面两句话的时候一定要记得,此时low>high sort(a,1,n);//从0开始是个好习惯,不过我费事改了
递归的空间复杂度平均为O(log2n)(函数调用栈)
稳定性:不稳定 PS:每一趟排序后会将一个元素(基准元素)放到最终位置上 优化:
在子序列规模较小时放弃递归调用快排,使用直接插入排序等完成后续的排序工作
尽量取可以将数据中分的枢轴元素,比如根据头、尾、中间三个元素的中间值等。
基本思想:每一趟在后面n-i+1个待排序元素中选择关键字最小的元素,作为有序子序列的第i个元素,直到第n-1趟完成。
堆排序是一种树形选择排序方式。特点是将L[1..n]看成是一棵完全二叉树的顺序存储结构,以此完成排序。 堆是一种特殊的二叉树,它的根节点的值大于/小于其两个孩子的值,这样根节点就是最大/最小的。通过不断提取最大值,可以得到一个序列,这个序列就是最终的排序结果。
i++;//取key较大的子节点的下标 k=i;//修改k值,以便继续向下筛选 A[k]=A[0];//被筛选结点的值放入最终位置 //参数k为向上调整的结点,也为堆的元素个数
空间效率:空间复杂度为O(1)
时间效率:建堆时间O(n),之后n-1次向下调整,每次调整的时间复杂度为O(h),故平均而言,时间复杂度为O(nlog2n)
7.5 归并排序和基数排序
将两个或两个以上的有序表组合成一个新的有序表。假定待排序表含有n个记录,则可以看成是n个有序子表,然后不断两两归并直到合成一个长度为n的有序表为止,这种排序方法称为2-路归并排序。
递归形式的2-路归并排序算法是基于分治额,对子表递归地排序。
它不是基于比较进行排序的,而是采用多关键字排序思想,又分为最高位优先排序和最低位优先排序。 以r为基数的最低位优先基数排序的过程:假设线性表由结点序列a0,a1,…,an-1构成,每个结点的关键字由d元组组成
分配:开始时,把Q0,Q1,…,Qr-1各个队列置成空队列,然后依次考察线性表中的每一个结点aj,如果aj的关键字的第i位符合要求,就把aj放入Qk队列中
收集:把Q0,Q1,…,Qr-1各个队列中的结点依次首尾相接,得到新的结点序列,从而组成新的线性表。
空间效率:一趟排序需要的辅助存储空间为r(r个队列),但以后的排序中重复使用这些队列,所以基数排序的空间复杂度为O(r)
时间复杂度:d趟分配和收集,一趟分配需要O(n),一趟收集需要O(r),所以基数排序的时间复杂度为O(d(n+r)),它与序列的初始状态无关。
7.6.1 内部排序算法的比较
7.7.1 外部排序的基本概念
在排序过程中需要多次进行内存和主存之间的交换,对外村文件中的记录进行排序后的结果仍然被放到原有文件中。这种排序方法就称为外部排序。
7.7.2 外部排序的方法
通常根据外存设备的不同分为磁盘文件排序和磁带文件排序两大类。磁盘是直接存取设备,磁带是顺序存取设备。 外部排序通常采用归并排序方法,有两个相对独立的阶段:
根据内存缓冲区的大小,将外存上含n个记录的文件分成若干长度为h的子文件,依次读入内存并利用有效的内部排序方法对它们进行排序,并将排序后得到的有序子文件重新写回外存(通常称这些有序子文件为归并段或顺串)
对这些归并段进行逐趟归并,使归并段逐渐由小变大,直至得到整个有序文件为止。
一般情况下,外部排序的总时间=内部排序所需的时间+外存信息读写的时间+内部归并所需的时间
即t_ES=rt_IS+dt_IO+S(n-1)t_mg,其中r是初始归并段的个数,t_IS是对每一个初始归并段进行内部排序的时间,d是访问外存块的次数,t_IO是每一个块的存取时间,S是归并趟数,n是每趟参加二路归并的记录个数,t_mg是每作一次内部归并,取得一个关键字最小记录的时间。
显然磁盘存取的时间远远大于内部排序和内部归并的时间,因此要提高外排序的速度,应该着力减少d,即I/O次数。
增大归并路数m,或减少初始归并段数r,都能减少归并趟数S,以减少读写磁盘次数d,达到提高外部排序速度的目的。
上节提到,可以增加归并路数m来减少归并趟数S,进而减少访问外存的次数。然而增加归并路数m又会增加算法内部排序的时间。因此不能使用普通的内部归并排序算法。 为了使内部归并不受m的增大的影响,引入了败者树。可以看作是一棵完全二叉树,每个叶结点存放各归并段在归并过程中参加比较的记录。内部结点用来记录左右子树中的失败者,让胜利者继续向上比较,一直到根节点。
m路归并的败者树深度为ceil(log2m),因此m个记录中选择最小关键字,最少需要ceil(log2(m))次比较,内部归并的比较次数就与m无关了。因此,只要内存空间允许,增大归并路数m可以有效减少归并树的高度,从而减少I/O次数d,提高外部排序的速度。
值得注意的是m并不是越大越好,m增大时要相应地增加输入缓冲区的个数。如果可供使用的内存空间不变,就势必要减少每个输入缓冲区的容量,使得内外存交换数据的次数增大。当m值过大时,虽然归并趟数减少,但读写外存的次数仍会增加。
如果采用前面介绍过的内部排序方法,将得到长度都相同的初始归并段。因此,需要使用新的算法那来生成初始归并段。 设初始待排文件FI,初始归并段文件为FO,内存工作区为WA,内存工作区可容纳w个记录。置换-选择算法的步骤如下:
从待排方法FI输入w个记录到工作区WA。
从内存工作区WA中选出其中关键字取最小值的记录,即为MINIMAX(以后再选出关键字比它大的记录归入本归并段,比它小的归入下一归并段)
若FI未读完,则从FI输入下一个记录到WA中。
/*这是一个在字符环境中,用ASCII码打印二叉树形状的算法。 采用层次遍法。 算法拙劣,仅供初学者做练习,(本人也是初学者,自学数据结构,刚好学到这二叉树这一章,搞几个二叉的例题,却不知道其构造形状,想调用图形API做个美观点的,却有点偏离本章的学习目的,只好用字符打印,
0 |
本书内容包括:C/C++快速入、入模拟、算法初步、数学问题、C++标准模板库(STL)、数据结构专题(二章)、搜索专题、图算法专题、动态规划专题、字符串专题、专题扩展。本书印有二维码,用来实时更新、补充内容及发布勘误的。
本书可作为计算机专业研究生入学考试复试上机、各类算法等级考试(如PAT、CSP等)的辅导书,也可作为“数据结构”科目的考研教材及辅导书内容的补充。本书还是学习C语言、数据结构与算法的入辅导书,非常适合零基础的学习者对经典算法进行学习。
这是一本零基础就能读懂的算法书籍,读者不需要因为自己没有语言基础而畏惧。书籍的第2章便是一个C语言的入教程,内容非常易懂,并且十分实用,阅读完这章就可以对本书需要的C语言基础有一个较好的掌握。
本书已经覆盖了大部分基础经典算法,不仅可以作为考研机试和PAT的学习教材,对其他的一些算法考试(例如CCF的CSP考试)或者考研初试的数据结构科目的学习和理解也很有帮助,甚至仅仅想学习经典算法的读者也能从本书中学到许多知识,本书还有配套的《算法笔记上机训练实战指南》
本书的作者是同样经历过考研机试和各类算法考试的专家型学长,知晓这类考试中的痛点,以及考生在学习算法时容易产生困惑的地方,因此可以把本书看作是学长为你奉献的满满的经验干货,这是有价值的东西。
本书的试印版本献给了浙大考研学子,并令当年的浙大考研机试平均分增加了十多分,收获了考生的大量。但作者并没有止步于此,经过了半年多时间的内容完善和补充之后,新的版本在新一年的考研机试中再次获得了考生的一致赞美。最后,在经过精心整理之后,书籍终于定稿,并编撰成书。
我们知道,纸质书籍的一个弱点就在于不能像软件一样随时更新内容,但本书采用了与二维码相结合的方式,使得本书变为能够随时更新内容的书籍,读者也可以随时从二维码中找到勘误。这种作者和读者能够相互沟通的方式让书籍变“活”了,也能够帮助提升读者对知识的理解。
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。