还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
数据结构与算法分析复习提纲欢迎来到上海交通大学计算机科学与技术学院的《数据结构与算法分析》课程复习提纲本课程(课程代码)是学年第二学期CS05012024-2025的核心课程,旨在帮助学生掌握计算机科学中最基础也是最重要的知识体系这份复习提纲涵盖了从基本数据结构到高级算法的所有关键概念,将帮助你系统地梳理课程内容,为期末考试做好充分准备无论你是初学者还是已有编程经验的学生,这份资料都能为你提供有价值的学习指导课程概述课程目标指定教材课程难点掌握基本数据结构和《数据结构与算法分时间复杂度分析、高算法设计方法,培养析》,作者级数据结构应用以及Mark学生的抽象思维能力,这本教在实际问题中选择合Allen Weiss和解决问题的能力,材系统地介绍了各种适的数据结构和算法,为后续专业课程学习数据结构和算法,并这些都需要学生反复打下坚实基础附有丰富的示例和练练习才能掌握习算法分析基础大表示法O用于描述算法在输入规模增长时性能变化的数学符号大关注的是算法在最坏情况下的渐O进行为,忽略常数系数和低阶项,帮助我们聚焦算法的核心效率特性时间与空间复杂度时间复杂度度量算法执行所需的操作数,而空间复杂度度量所需的内存空间这两者通常存在权衡关系,优化一方可能会导致另一方的性能下降分析情境算法分析通常考虑三种情境最坏情况(保证上限)、平均情况(日常性能)和最好情况(理想条件)实际应用中,我们通常更关注最坏和平均情况常见复杂度从最优到最差常数时间、对数时间、线性时间、线性对数O1Olog n On On log n时间、平方时间理解这些复杂度等级对算法选择至关重要On²复杂度分析实例简单循环On单层循环遍历个元素的数组,操作次数与输入规模成正比n例如查找数组中的最大值、计算数组元素和等操作嵌套循环On²两层嵌套循环,外层和内层均为次迭代,总操作次数约为n例如冒泡排序、选择排序等简单排序算法n²二分查找Olog n每次将搜索范围减半,是对数级算法的典型代表这类算法在处理大规模数据时非常高效,但要求数据已排序分治算法On log n将问题分解为子问题,分别解决后合并结果例如归并排序、快速排序等高效排序算法通常具有此复杂度指数级算法O2^n操作次数随输入规模指数增长,通常出现在需要考虑所有可能组合的场景例如未经优化的斐波那契递归、旅行商问题的暴力解法递归算法递归优化技术递归复杂度分析尾递归是一种特殊形式,函数的最后一个操递归定义与特性递归算法的时间复杂度分析通常使用递推关作是调用自身,可以被编译器优化为迭代形递归是一种函数调用自身的解决问题的方法,系式,如,其中是式,避免栈溢出记忆化搜索(缓存已计算Tn=aTn/b+fn a具有自相似的特性递归算法必须包含基本子问题数量,是子问题规模,是分解结果)也是常用的递归优化技术,可以显著n/b fn情况(终止条件)和递归情况,通过将复杂和合并的代价通过主定理可以求解许多常减少重复计算问题分解为更简单的子问题来解决见的递归复杂度递归实例分析阶乘计算斐波那契数列汉诺塔问题阶乘是递归的经典例子×定义为,基经典的递归问题,将个盘子从源柱移n!=n Fn=Fn-1+Fn-2n,基本情况是时间复本情况是朴素动到目标柱,需要步其递n-1!0!=1F0=0,F1=12^n-1杂度为,空间复杂度也为,递归实现的时间复杂度是,但归分解为移动个盘子到辅助柱,On On O2^n n-1因为需要层递归调用栈使用记忆化可以优化至移动最大盘子到目标柱,再将个n Onn-1盘子从辅助柱移到目标柱int factorialintn{int fibintn{时间复杂度为,这也反映了问O2^nif n==0return1;if n=1return n;题的内在复杂性return n*factorialn-return fibn-1+1;fibn-2;}}数组与字符串数组基本特性多维数组数组是连续内存空间中相同类二维及更高维数组可以表示矩型元素的集合,支持时间阵、图像和更复杂的数据关系O1复杂度的随机访问数组是最在内存中,多维数组通常以行基础的数据结构,是许多其他优先或列优先的方式存储正数据结构的构建基础然而,确理解多维数组的寻址公式对数组的大小通常是固定的,插提高访问效率很重要,例如在入和删除元素(尤其是在中间二维数组中,元素的地址[i][j]位置)的效率较低,需要计算涉及行数、列数和基地址On时间字符串处理字符串是字符数组的特殊形式,在编程中有广泛应用常见的字符串操作包括连接、子串提取、查找和替换高效的字符串算法如、KMP可以在时间内完成模式匹配,相比朴素的Boyer-Moore On+m算法有显著提升Onm链表基础单向链表每个节点包含数据和指向下一节点的指针双向链表节点同时包含前向和后向指针循环链表最后节点指向首节点形成环链表是一种线性数据结构,与数组不同,链表的元素在内存中不是连续存储的,而是通过指针相连链表的主要优势在于插入和删除操作的高效性(理想情况下为),以及动态内存分配的灵活性O1链表的主要缺点是不支持随机访问,查找特定元素需要时间,且额外的指针存储会增加内存开销在实际应用中,链表适用于On频繁插入删除但较少随机访问的场景,如实现队列、栈等抽象数据类型链表操作详解链表的基本操作包括插入、删除、遍历和特殊操作(如反转、环检测)插入和删除节点的时间复杂度为,前提是已知节O1点位置;如需先查找节点,则总体复杂度为On链表反转是一个经典问题,可通过迭代或递归实现检测环形链表通常使用快慢指针法(Floyds Cycle-Finding),快指针每次移动两步,慢指针移动一步,若存在环,两指针最终会相遇这些操作既是面试常见问题,也是理Algorithm解指针操作和链表结构的绝佳练习栈Stack栈的定义与特性栈的实现方式栈是一种遵循后进先出原则的抽象数据类型栈有两种主要实现方式基于数组的顺序栈和基于链表的链式栈顺序栈LIFO:Last-In-First-Out它限制了数据的访问方式,只允许在一端(称为栈顶)进行操作,使用固定大小的数组,可能面临栈溢出问题,但内存利用率高;链式栈则ADT这使得栈成为一种具有受限访问特性的线性数据结构使用动态分配的内存,避免了大小限制,但有额外的指针开销栈的这种特性使其在解决特定类型问题时非常有效,尤其是那些需要撤销两种实现的基本操作复杂度都是,选择哪种实现方式主要取决于应用O1最近操作或跟踪嵌套结构的场景场景和系统限制基本操作描述时间复杂度将元素推入栈顶pushx xO1移除并返回栈顶元素pop O1查看栈顶元素但不移除peek/top O1检查栈是否为空isEmpty O1返回栈中元素个数size O1栈的应用函数调用栈计算机程序使用栈来管理函数调用和返回每当发生函数调用,程序将返回地址、局部变量和参数压入栈;函数完成后,这些信息被弹出,控制权返回到调用点递归函数特别依赖这一机制括号匹配验证栈可以高效验证表达式中的括号是否匹配算法扫描表达式,遇到开括号则入栈,遇到闭括号则与栈顶比较,若匹配则弹出栈顶最终栈为空表示所有括号都正确匹配表达式求值将中缀表达式如转换为后缀表达式如使用两个栈一个用于运算符,根据优先级决定入栈出栈;另一个用于操作数后缀表达式计算则只需一个栈,顺序扫描表达a+b*cabc*+式即可递归转迭代使用栈可以将递归算法转换为非递归(迭代)版本,避免过深递归导致的栈溢出问题例如,树的深度优先遍历可以使用栈来实现,无需递归调用队列Queue特性FIFO先进先出原则定义ADT支持和操作enqueue dequeue实现方式顺序队列、循环队列和链式队列队列是一种遵循先进先出原则的线性数据结构与栈不同,队列在一端(队尾)添加元素,在另一端(队FIFO:First-In-First-Out首)移除元素队列的抽象数据类型定义包括两个核心操作(入队)和(出队)enqueue dequeue队列的实现方式有多种顺序队列使用数组实现,但可能面临假溢出问题;循环队列通过将队列头尾相连解决了这一问题;链式队列则使用链表实现,避免了大小限制在实际应用中,队列广泛用于任务调度、消息缓冲、广度优先搜索等场景,是计算机科学中的基础数据结构特殊队列结构双端队列优先队列Deque双端队列允许在两端进行插入和删除操优先队列是一种特殊的队列,其中每个作,结合了栈和队列的特性可以用数元素都有一个优先级,出队顺序按优先组或链表实现,所有操作的时间复杂度级而非入队顺序决定通常使用堆实现,均为双端队列在需要同时支持插入和删除操作的时间复杂度为O1Olog和操作的场景非常有用FIFO LIFOn前端操作应用任务调度、事件处理•push_front,•pop_front操作•insert,后端操作•push_back,extractMax/extractMinpop_back循环队列循环队列是一种特殊的顺序队列,通过将队列首尾相连解决了普通顺序队列的假溢出问题它使用模运算来处理队列索引的循环,有效利用数组空间头尾指针和•front rear判满条件•rear+1%size==front索引计算•index+1%size树结构基础树的定义二叉树特性树是一种由节点和连接节点的边组成每个节点最多有两个子节点,区分为的非线性层次结构,没有环路左子节点和右子节点特殊二叉树树的平衡性满二叉树所有内部节点都有两个子节平衡树的任意节点左右子树高度差不点,完全二叉树除最后一层外都是满超过一个固定值,提高操作效率的树是计算机科学中最重要的非线性数据结构之一,它模拟了具有层次关系的数据树的术语包括根节点(唯一的顶层节点)、内部节点(有子节点的节点)、叶节点(没有子节点的节点)、深度(从根到节点的路径长度)和高度(从节点到最远叶节点的路径长度)二叉树遍历312基本遍历方式层序遍历实现方法前序、中序和后序是深度优先的遍历方式广度优先的遍历方式,使用队列实现每种遍历都可以通过递归或非递归实现前序遍历中序遍历后序遍历Preorder InorderPostorder访问顺序根节点左子树右子树这种方式首访问顺序左子树根节点右子树对于二叉搜访问顺序左子树右子树根节点后序遍历先------先访问当前节点,然后递归地遍历左子树,最后索树,中序遍历会产生有序的节点序列,这是其处理子节点再处理父节点,常用于释放树的内存递归地遍历右子树前序遍历常用于创建树的副重要特性中序遍历常用于二叉搜索树的有序数(先删除子节点再删除父节点)或计算目录大小本或表达式树的前缀表示据处理等需要自下而上处理的场景void preorderNode*root{void inorderNode*root{void postorderNode*root{if root==nullptr return;if root==nullptr return;if root==nullptr return;visitroot;//访问根节inorderroot-left;//遍历左子postorderroot-left;//遍历左点树子树preorderroot-left;//遍历左子visitroot;//访问根节postorderroot-right;//遍历右树点子树preorderroot-right;//遍历右inorderroot-right;//遍历右子visitroot;//访问根子树树节点}}}二叉搜索树BST性质查找与插入删除操作平衡问题BST对于任意节点,其左子树的所有节点基于比较大小,沿树路径向下,平均删除叶节点最简单,删除有两个子节最坏情况下可能退化为链表,导致值小于该节点值,右子树的所有节点复杂度点的节点最复杂,需要找后继节点替复杂度Olog n On值大于该节点值代二叉搜索树是一种特殊的二叉树,它支持高效的查找、插入和删除操作的核心优势在于其有序性,对进行中序遍历可以得到有序序列这一特性使BST BST BST BST成为实现集合、映射等抽象数据类型的理想选择然而,的性能严重依赖于树的平衡性在最坏情况下(如按顺序插入元素),可能退化为链表,导致操作复杂度退化至为解决这一问题,人们发明了BSTBSTOn AVL树、红黑树等自平衡的二叉搜索树变体,它们通过旋转操作维持树的平衡,确保的性能Olog n平衡二叉树平衡因子概念平衡因子是指节点的左子树高度减去右子树高度Balance Factor在树中,每个节点的平衡因子绝对值不超过,即这AVL1{-1,0,1}一限制确保树的高度始终保持在,从而保证所有操作的对数时Olog n间复杂度树旋转操作AVL当插入或删除节点导致树失去平衡时,需要通过旋转操作恢复AVL平衡单旋转包括左旋和右旋,用于处理单侧失衡;双旋转包括先左后右和先右后左,用于处理之字形失衡旋转操作都是LR RL时间复杂度O1性能与应用树的严格平衡保证了最坏情况下也有的性能,这对AVL Olog n于查询密集型应用非常有利但维护这种严格平衡的代价是插入和删除操作可能需要较多旋转树常用于对查询性能要求高AVL但修改频率较低的场景红黑树1红黑树五大性质2插入与删除操作红黑树是一种自平衡的二叉搜索树,通过节点着色(红色或黑色)和特定红黑树的插入和删除操作比树更为复杂,需要结合节点着色和旋转AVL规则维持平衡五大性质包括根节点必须是黑色;红节点的子节点必须操作来维持红黑树的性质新插入的节点初始为红色,然后通过调整着色是黑色;每个叶节点()是黑色;从根到任意叶节点的所有路径包含和结构恢复平衡删除操作则更为复杂,需要根据不同情况选择适当的处NIL相同数量的黑节点;每个节点要么是红色要么是黑色理策略3平衡策略与性能4应用场景红黑树的平衡条件比树宽松,不要求左右子树高度差严格小于等于,红黑树在实际应用中非常广泛,是许多语言标准库中实现有序集合和映射AVL1而是通过保证没有连续的红节点和黑高度平衡来实现整体平衡这使得红的首选数据结构例如,中的和,中的C++STL mapset JavaTreeMap黑树在插入和删除时平均需要更少的旋转操作,对于频繁修改的场景更为和,以及内核中的调度算法,都使用了红黑树作为底层实TreeSet Linux高效现树与树B B+树结构与特性树改进与优势实际应用B B+树是一种自平衡的多路搜索树,专为树是树的一种变体,在数据库系树和树广泛应用于数据库系统和B B+B BB+磁盘或其他二级存储设备设计与二统设计中更为常用它的非叶节点只文件系统中,成为处理大规模数据的叉树不同,树的节点可以有多个子节存储键值信息作为索引,所有数据都标准索引结构大多数关系型数据库B点,通常对应磁盘块大小树的所有存储在叶节点,且叶节点通过指针连如的存储引擎使用B MySQLInnoDB B+叶节点都在同一层,确保了查找操作接形成有序链表,便于范围查询树作为索引结构,而文件系统如NTFS的平衡性则使用树变体B非叶节点仅存储索引,可存储更多•每个节点可以容纳多个键值和指针键值、等数据库系统••MySQL Oracle所有叶节点具有相同深度叶节点包含所有数据,并通过链表、等文件系统•••NTFS EXT4连接降低了树的高度,减少磁盘大型键值存储系统•I/O•查找路径长度相同,查询性能稳定•范围查询高效,只需遍历叶节点链•表堆Heap堆的结构与性质完全二叉树形式,满足堆序性质数组实现高效的随机访问和空间利用率基本操作插入和删除根节点需要重新平衡堆排序利用堆性质实现的原地排序算法堆是一种特殊的完全二叉树,根据其性质分为最大堆(父节点值大于或等于子节点值)和最小堆(父节点值小于或等于子节点值)堆通常使用数组实现,对于索引为的节点,其左子节点索引为,右子节点索引为,父节点索引为i2i+12i+2i-1/2堆的核心操作包括向上调整()和向下调整()向上调整在插入新元素后使用,将元素逐级与父节点比较并交换,直到满足堆序性质;sift-up sift-down向下调整在删除根节点后使用,将新根节点与子节点比较并交换,维持堆的结构这些操作的时间复杂度均为,使堆成为高效的优先队列实现Olog n优先队列哈希表哈希函数设计冲突解决将任意大小的数据映射到固定大小的值,不同键映射到相同哈希值的处理策略,影是哈希表高效性能的关键响查找性能动态扩容实际应用基于负载因子自动调整表大小,平衡空间广泛用于实现字典、缓存和数据库索引等和时间效率哈希表是一种基于哈希函数直接访问元素的数据结构,理想情况下提供的查找、插入和删除操作哈希函数设计遵循的原则包括计算O1高效性、均匀分布性、雪崩效应(输入微小变化导致输出显著不同)等冲突解决有两种主要方式开放寻址法在原表中寻找下一个可用位置(线性探测、二次探测或双重哈希),适合数据量可预测且较小的情况;链地址法则在每个桶中使用链表或其他数据结构存储冲突元素,更适合动态变化的数据集当负载因子(元素数量与表大小之比)超过阈值时,通常会触发表的扩容和重新哈希,以维持高效性能哈希表性能分析负载因子开放寻址平均查找长度链地址平均查找长度图论基础图的概念与类型图的表示方法图是由顶点集合和连接顶点图的计算机表示有多种方式,选择哪种表示Graph Vertex的边集合组成的数据结构,用于表示方法取决于图的特性和算法需求常见的表Edge实体之间的关系根据边的特性,图可分为示方法包括有向图(边有方向)和无向图(边无方向);邻接矩阵使用×的矩阵表示,适合•V V根据边的权重,可分为带权图和无权图稠密图和需要快速判断两点间是否有边的场景,空间复杂度OV²简单图不含自环和平行边•邻接表每个顶点维护一个链表存储其•完全图任意两顶点间都有边邻接点,适合稀疏图,空间复杂度•连通图任意两顶点间存在路径OV+E•边集数组直接存储所有边的信息,适二分图顶点可分为两组,边只连接不••合某些只关注边的算法,如算法同组顶点Kruskal图的基本操作图的基本操作包括添加删除顶点、添加删除边、查找顶点的所有邻接点等不同的表示方法对//这些操作的效率有显著影响例如邻接矩阵查询两点间是否有边,查找所有邻接点•O1OV邻接表查询两点间是否有边,查找所有邻接点•Odegree Odegree图的遍历深度优先搜索和广度优先搜索是处理图结构的基本算法•DFS BFS图的遍历深度优先搜索广度优先搜索DFS BFS深度优先搜索是一种沿着图的深度方向探索的遍历算法它从起始顶点开始,沿着一条路径广度优先搜索是一种按层次探索的遍历算法它从起始顶点开始,先访问所有相邻顶点,然尽可能深入,直到无法继续前进时回溯到前一个有未访问邻接点的顶点,继续探索后再访问下一层顶点总是优先访问离起始顶点距离最近的顶点BFS通常使用递归或栈实现,非常适合解决连通性、路径查找、拓扑排序和环检测等问题通常使用队列实现,非常适合解决最短路径、连通区域标记和二分图检测等问题在邻DFS BFS在邻接表表示下,的时间复杂度为,空间复杂度为接表表示下,的时间复杂度也为,空间复杂度为DFS OV+E OVBFS OV+E OVvoidDFSGraph G,Vertex v{void BFSGraphG,Vertex start{visited[v]=true;Queue Q=new Queue;//处理顶点v visited[start]=true;for每个与v相邻的顶点u{Q.enqueuestart;if!visited[u]{DFSG,u;while!Q.isEmpty{}Vertex v=Q.dequeue;}//处理顶点v}for每个与v相邻的顶点u{if!visited[u]{visited[u]=true;Q.enqueueu;}}}}最小生成树生成树定义生成树是连通图的一个子图,它包含图中所有顶点,且边数最少(恰好为顶点数减一),形成一棵无环树最小生成树是在带权图中总权重最小的生成树问题在网络设计、聚类分析等领域有广泛应用MST算法Prim算法从单个顶点开始,逐步扩展每步选择一条权重最小的边,Prim MST该边连接中的顶点和不在中的顶点使用优先队列实现时,时间复MST MST杂度为算法适合稠密图OE logV Prim算法Kruskal算法按边的权重从小到大排序,逐一考虑每条边如果添加该边不Kruskal会在当前构建的中形成环,则将其添加到中使用并查集检测环,MST MST时间复杂度为算法适合稀疏图OE logE Kruskal实际应用最小生成树算法广泛应用于网络设计(如电信网络、计算机网络的布线)、近似算法(如解决旅行商问题)和聚类分析(根据对象间相似度聚类)等领域最短路径算法问题定义最短路径问题是图论中的经典问题,寻找图中从源点到目标点的总权重最小的路径根据源点和目标点的数量,可分为单源最短路径(一个源点到所有点)、单目标最短路径、单对最短路径和多源最短路径(所有点对之间)等变种算法Dijkstra算法解决带非负权边的单源最短路径问题它维护一个距离数组,表示从Dijkstra源点到各点的最短距离估计,采用贪心策略逐步确定最短路径使用优先队列实现时,时间复杂度为算法不适用于有负权边的图OE logV Dijkstra算法Bellman-Ford算法也解决单源最短路径问题,但可以处理带负权边的图(只要没Bellman-Ford有负权回路)算法通过对所有边进行次松弛操作,确保找到最短路径时间V-1复杂度为,虽然比算法慢,但适用范围更广OV·E Dijkstra算法Floyd-Warshall算法解决多源最短路径问题,计算图中所有顶点对之间的最短路径Floyd-Warshall它基于动态规划思想,时间复杂度为虽然复杂度较高,但算法简单,适用于OV³稠密图和需要计算所有顶点对最短路径的场景拓扑排序有向无环图特性拓扑排序算法有向无环图是一种没有有向环的有向图具有许多特殊性质,如一定存在拓扑排序、拓扑排序是对的顶点进行排序,使得对于图中的每条有向边,顶点在排序中都出现在顶点之前拓扑排序的结DAG,Directed AcyclicGraph DAGDAG u,v uv顶点可以按层次划分等常用于表示任务依赖关系、程序执行流程等结构果可能不唯一DAG在中,如果存在一条从顶点到顶点的有向路径,则在拓扑排序中必须出现在之前这种偏序关系是拓扑排序的基础基于的实现使用后序遍历,然后将结果反转基于入度的实现(算法)首先将所有入度为的顶点加入队列,DAG uv uv DFSKahn0然后依次处理这些顶点,减少其邻接点的入度,处理新产生的入度为的顶点0//Kahn算法List topologicalSortGraphG{Queue q=new Queue;List result=new List;//将所有入度为0的顶点入队for每个顶点v{if v.inDegree==0{q.enqueuev;}}while!q.isEmpty{Vertex v=q.dequeue;result.addv;for每个v的邻接点u{u.inDegree--;if u.inDegree==0{q.enqueueu;}}}//检查是否有环if result.size!=G.vertexCount{throw newException图中存在环;}return result;}并查集等价关系与集合表示并查集是一种维护不相交集合的数据结构,支持合并集合和Union-Find查询元素所属集合的操作它通常用于处理等价关系问题,如连通性分析、最小生成树算法中的环检测等并查集使用树形结构表示集合,每个集合的所有元素形成一棵树,树根作为集合的代表元素基本操作与优化并查集的核心操作是(查找元素所属集合的代表)和(合并Find Union两个集合)朴素实现的时间复杂度较高,但通过两种关键优化可显著提升性能路径压缩(在操作中将路径上的所有节点直接连到根节Find点)和按秩合并(将较小的树连接到较大的树下)近似常数时间复杂度经过路径压缩和按秩合并优化后,并查集的操作复杂度接近于常数级别严格来说,复杂度为,其中是阿克曼函数的反函数,Oαnαn在实际应用中可视为常数(即使非常大,也不超过)这使nαn5得并查集成为解决大规模等价关系问题的高效工具排序算法I排序算法II希尔排序快速排序插入排序的改进版,通过比较不相邻元素,分治策略,选择枢轴元素并划分数组,递归逐步缩小增量排序子数组枢轴选择复杂度分析影响快排性能的关键因素,好的选择可避免平均,最坏可能退化为On log n On²最坏情况希尔排序是插入排序的一种变体,通过比较相距一定增量的元素,逐步减小增量直到为其时间复杂度取决于增量序列的选择,一般在1On log²n到之间,但在实践中表现良好,尤其是对中等规模的数据On^
1.5快速排序是实际应用中最常用的排序算法之一,其平均时间复杂度为算法的关键步骤是选择枢轴并将数组划分为小于枢轴和大于On logn pivot枢轴的两部分枢轴选择策略对性能影响很大,常见方法包括选择第一个元素(简单但可能导致最坏情况)、随机选择(避免最坏情况)和三数取中(更加平衡)在最坏情况下(如已排序数组),快排可能退化为,但通过优化可基本避免这种情况On²排序算法III分解阶段将数组递归地分解为两个子数组,直至规模为1合并阶段合并两个已排序的子数组,产生更大的有序数组时间分析分解层,每层合并,总体Olog nOn On logn空间分析需要辅助空间,是一个重要的限制因素On归并排序是一种基于分治思想的排序算法,其核心思想是将大问题分解为小问题,解决小问题后合并结果归并排序的过程分为两个主要阶段分解和合并在分解阶段,数组被递归地分成两半,直到每个子数组只包含一个元素;在合并阶段,相邻的子数组被合并成更大的有序数组归并排序最大的优势在于其稳定的时间复杂度,无论输入如何,都保持的性能,这使其在处On logn理大规模数据时非常有效此外,归并排序是稳定的,保持相等元素的相对顺序然而,其主要缺点是需要的额外空间来存储临时数组,这在内存受限的环境中可能是一个问题归并排序在外部排序On(数据无法全部加载到内存)中也有重要应用排序算法IV堆排序算法步骤性能与应用分析堆排序是一种利用堆数据结构进行的原地排序算法,分为两堆排序的总体时间复杂度为,这一性能在最好、On logn个主要阶段建堆和排序平均和最坏情况下都保持不变,与输入数据的分布无关建堆阶段将输入数组转换为最大堆(升序排序)或最小与其他的排序算法相比,堆排序具有以下特点
1.On logn堆(降序排序)空间复杂度为,是原地排序算法,不需要额外空间•O1排序阶段重复执行交换堆顶元素到末尾和堆化操作
2.不稳定排序,不保证相等元素的相对顺序•在真实世界数据上通常比快速排序慢,但不会出现快排最•尽管每次堆化操作的时间复杂度为,但建堆的总体Olog n坏情况时间复杂度可以证明为,而不是直观上的On Onlogn适合需要找出最大最小元素的场景,如问题•/TopK这是因为大多数节点在树的底层,需要进行的比较和交换操作较少线性时间排序计数排序桶排序基数排序计数排序利用元素的值直接确定其在排序桶排序将元素分配到有限数量的桶中,再基数排序是一种多关键字排序算法,从最后数组中的位置它通过统计小于等于每对每个桶单独排序当输入数据均匀分布低有效位()或最高有效位()LSD MSD个元素的元素个数,计算出元素的正确位时,桶排序可达到线性时间复杂度适用开始,逐位进行排序适用于定长的数字、置适用于元素范围较小的整数排序,如于浮点数排序或可以映射到桶的数据时字符串等时间复杂度为,其Odn+k的成绩排序时间复杂度,间复杂度取决于映射函数和桶内排序算法,中是位数,是每位可能的取值范围基0-100On+k dk空间复杂度,其中是元素的取值理想情况下为,但最坏情况下可能退数排序通常结合计数排序来处理每一位,On+k kOn范围化为是一种非比较排序On²搜索算法输入规模顺序搜索二分搜索插值搜索贪心算法贪心策略原理贪心算法是一种在每一步选择中都采取当前状态下最优选择的问题解决方法它通过局部最优选择,期望导致全局最优解贪心算法的设计往往直观简单,但证明其正确性可能很复杂,需要证明局部最优选择能导致全局最优解适用条件贪心算法能正确解决问题通常需要满足两个关键条件最优子结构(问题的最优解包含子问题的最优解)和贪心选择性质(局部最优选择导致全局最优解)如果问题不具备这些特性,贪心算法可能无法得到正确结果经典问题活动选择问题在互不兼容的活动集合中选择最大兼容子集,贪心策略是按结束时间排序,每次选择最早结束的活动霍夫曼编码构造最优前缀编码,贪心策略是每次合并频率最小的两个节点这些问题都能通过贪心算法得到最优解局限性并非所有问题都适合贪心算法,如背包问题,贪心策略(按价值密度排序)不一定0-1得到最优解在实践中,需要仔细分析问题特性,确认贪心策略的正确性某些情况下,即使贪心算法不能得到最优解,也可能作为近似算法提供可接受的次优解动态规划基础重叠子问题问题的递归解法中存在重复求解的子问题最优子结构问题的最优解包含子问题的最优解实现方法备忘录自顶向下和表格法自底向上算法比较区别于分治和贪心的关键特性动态规划是一种通过将复杂问题分解为更简单的子问题来解决问题的方法与分治算法不同,动态规划处理的子问题往往不是相互独立的,而是重叠的,这意味着同一子问题会在算法执行过程中被多次求解动态规划通过存储已解决子问题的结果,避免重复计算,从而提高效率动态规划有两种主要实现方式备忘录方法(自顶向下)使用递归加缓存,当需要解决子问题时先检查是否已有结果;表格方法(自底向上)则从最小的子问题开始,逐步构建更大问题的解与贪心算法相比,动态规划考虑所有可能的选择,而不仅仅是当前最优选择,因此能解决更广泛的问题,尽管可能需要更多的计算资源经典动态规划问题I斐波那契数列最长公共子序列LCS递归解法导致指数级时间复杂度,但使用动态规划可将其优化为,空间复杂度也可优化为这是理给定两个序列,找出它们共有的最长子序列(不要求连续)这是生物信息学、文件比较等领域的基础问题使用二O2^nOnO1解动态规划优势的最简单例子维表,时间和空间复杂度均为DP Om*n状态转移方程如果当前字符相同,则长度;否则取两种不匹配情况的最大值LCS+1//自底向上方法int fibintn{if X[i]==Y[j]if n=1return n;DP[i][j]=DP[i-1][j-1]+1int a=0,b=1,c;elsefor inti=2;i=n;i++{DP[i][j]=maxDP[i-1][j],DP[i][j-1]c=a+b;a=b;b=c;}return b;}经典动态规划问题II背包问题完全背包问题空间优化0-1给定个物品,每个物品有重量和价值,在总与背包问题类似,但每种物品可以选择任意次(无背包问题的动态规划解法可以进行空间优化,将二维数n w[i]v[i]0-1重量不超过的情况下,选择物品使总价值最大每个限供应)这改变了状态转移方程,需要考虑当前物品组压缩为一维数组这是因为计算时只需要用W DP[i][j]物品只能选择或次,因此称为背包问题可能被多次选择的情况到上一行的信息010-1动态规划解法使用二维数组表示考虑前个物品,状态转移方程变为对于背包问题,需要逆序更新数组,防止物品DP[i][j]i0-1DP重量不超过的最大价值状态转移方程被重复选择jDP[i][j]=maxDP[i-1][j],DP[i][j-w[i]]DP[i][j]=maxDP[i-1][j],DP[i-1][j-+v[i]for i=1to n:w[i]]+v[i]for j=W tow[i]step-1:注意这里使用而不是,DP[j]=maxDP[j],DP[j-w[i]]+DP[i][j-w[i]]DP[i-1][j-w[i]]表示可以重复选择当前物品v[i]而完全背包问题则需要正序更新,允许物品被重复选择回溯算法回溯思想回溯算法是一种通过探索所有可能解的系统方法,它在解决过程中尝试不同的路径,当发现当前路径不可行时回退(回溯)到前一个决策点,尝试其他可能性这种试探回退的策略本质上是一种深度优先搜索+解空间构建回溯算法将问题的解空间表示为一棵树,每个节点代表一个部分解算法从根节点开始,逐步构建解决方案,直到找到完整解或确定当前路径无解回溯的关键是确定何时继续探索,何时停止并回退剪枝策略为提高效率,回溯算法通常使用剪枝技术,在探索过程中尽早丢弃无法得到有效解的路径这通过约束条件检查实现,当检测到当前路径违反问题约束时,立即回溯,避免无谓的搜索皇后问题N在×棋盘上放置个皇后,使它们互不攻击回溯算法对每行尝试不同列位置,检N NN查是否与已放置皇后冲突如有冲突,尝试下一列;如无冲突,继续处理下一行此问题展示了回溯和剪枝的典型应用字符串算法算法算法前缀树KMP Boyer-Moore Trie算法是一种高算法是另一种高效的字是一种树形数据结构,专门用于Knuth-Morris-Pratt Boyer-Moore Trie效的字符串匹配算法,它通过预处理符串匹配算法,它通过从右向左比较高效存储和检索字符串集合每个节模式串,构建部分匹配表或称模式串,利用坏字符规则和好后缀规点代表一个字符,从根到叶节点的路PMT失配函数数组,避免不必要的则来跳过不必要的比较在实践中,径表示一个完整字符串支持快NextTrie字符比较尤其是对于长文本和长模式,速的前缀匹配和字符串查找,常用于Boyer-通常比更快自动补全、拼写检查和路由等应用Moore KMPIP算法的核心思想是利用已经部分KMP匹配的信息,当出现不匹配时不必完坏字符规则当不匹配发生时,将模全回退,而是根据失配函数跳转到合式串移动到使坏字符与模式中最右侧的主要操作包括插入、查找和删Trie适位置继续比较这将时间复杂度从相同字符对齐的位置好后缀规则除,在字符集大小为、最长字符串长k朴素算法的降低到利用已匹配的后缀信息来确定移动距度为的情况下,这些操作的时间复杂Omn Om+n L离度均为,与存储的字符串总数无OL关高级数据结构I线段树树状数组应用场景线段树是一种用于处理区间查询和修改的树形数据结树状数组或这些高级数据结构在许多算法问题和实际应用中非常Binary IndexedTree FenwickTree构每个节点代表一个区间,父节点的区间是子节点是一种支持高效单点更新和前缀和查询的数据结构有用区间的并集线段树支持高效的区间求和、最大值、相比线段树,树状数组实现更简单,内存消耗更小,线段树区间最值查询、区间和查询、区间修改•最小值等查询操作,以及单点和区间更新操作但功能相对有限等建树时间复杂度单点更新时间复杂度•On•Olog n树状数组动态前缀和、逆序对计数、二维区域•查询时间复杂度前缀和查询时间复杂度和查询等•Olog n•Olog n更新时间复杂度区间和查询通过两次前缀和查询实现在线算法处理动态变化的数据集,随时响应查•Olog n••询线段树的一个重要优化是懒惰传播树状数组基于数的二进制表示,利用操作(获Lazy lowbit计算几何处理区间重叠、覆盖等问题,它延迟对子节点的更新,直到子节取最低位的所表示的值)进行高效更新和查询•Propagation1点的信息被需要,从而提高区间更新的效率高级数据结构II跳表Skip List跳表是一种基于有序链表的数据结构,通过增加多层索引来加速搜索过程每一层的索引节点以概率方式选择,形成一个层次化的结构跳表提供了Olog n的期望搜索、插入和删除时间复杂度,是红黑树等复杂平衡树的一种替代方案跳表实现简单,且在并发环境下更易于锁定局部区域,因此在等系统中Redis被广泛应用伸展树Splay Tree伸展树是一种自调整的二叉搜索树,它在每次访问操作(查找、插入、删除)后,通过一系列旋转将被访问的节点移动到根位置这种自调整机制利用了局部性原理,使频繁访问的元素更容易被找到虽然单次操作最坏时间复杂度为,但摊还分析表明其均摊复杂度为伸展树不需要维护平衡信息,On Olog n实现相对简单过滤器Bloom过滤器是一种空间效率高的概率性数据结构,用于测试元素是否属于集合它使用多个哈希函数将元素映射到位数组的不同位置,并将这些位置标记Bloom为查询时,如果所有哈希位置都是,则元素可能在集合中;如果任一位置为,则元素肯定不在集合中这种结构可能产生假阳性(误报),但不会有110假阴性(漏报)过滤器广泛用于缓存、垃圾邮件过滤和网络路由等场景Bloom完全性理论NP复杂度类别、和完全问题的区分与关系P NP NP多项式归约证明完全性的核心技术NP典型完全问题NP3旅行商、图着色、子集和等经典问题近似算法4处理完全问题的实用方法NP计算复杂度理论中,类问题是可以在多项式时间内解决的问题,而类问题是可以在多项式时间内验证解的正确性的问题必定包含在中,但是否P NPPNPP等于是计算机科学中著名的未解问题完全问题是中最难的一类问题,任何问题都可以在多项式时间内归约到完全问题NP NP NP NP NP多项式归约是证明问题完全性的标准方法首先证明问题属于类,然后证明一个已知的完全问题可以多项式归约到该问题经典的完全问题包NPNPNPNP括布尔可满足性问题、旅行商问题、图的顶点覆盖、子集和问题等对于这类问题,通常采用近似算法、启发式算法、参数化算法或随机化算法等方SAT法来寻找实际可用的解决方案算法设计技巧分治法将问题分解为更小的独立子问题,解决后合并结果减治法将问题规模缩小,递归解决剩余部分变治法将原问题转化为更容易解决的等价问题迭代与递归4解决问题的两种基本范式,各有优缺点算法设计技巧是解决计算问题的系统方法分治法()将问题分解为独立子问题,适用于归并排序、快速排序、二分搜索等;减治法(Divide and Conquer Decrease)则是通过减少问题规模,如二分搜索、欧几里得算法;变治法()通过等价变换简化问题,如霍纳法则计算多项式、前缀andConquerTransform andConquer和优化区间查询在实现算法时,递归和迭代是两种基本范式递归实现往往更简洁易懂,但可能导致栈溢出和重复计算;迭代实现通常更高效,但可能较复杂实际应用中,常见的优化技巧还包括预计算(空间换时间)、缓存重复计算结果(记忆化)、使用更高效的数据结构、延迟计算以及位运算优化等选择合适的技巧需考虑问题特性、时间和空间限制以及代码可维护性空间与时间权衡空间换时间时间换空间空间换时间是算法设计中的常用策略,通过牺牲内存空间来提高执行速度与此相反,时间换空间策略通过增加计算操作减少内存使用常见场景包括经典案例包括哈希表(空间获得查找)、预计算表(如三角函实时计算而非存储结果、压缩算法(用解压缩时间换取存储空间)、迭代生OnO1数表)、缓存机制(如缓存)以及使用额外数据结构(如索引)加速查成而非存储完整序列等这种策略适用于内存受限但计算资源相对充足的环LRU询这种策略在内存资源充足但对响应时间要求高的场景尤为有效境,如嵌入式系统或大规模数据处理缓存设计实际应用中的平衡缓存是空间换时间的典型应用,通过存储频繁访问的数据来减少重复计算在实际工程中,时间空间权衡需要考虑多方面因素系统环境(内存限制、高效的缓存系统需要考虑缓存大小(内存限制)、替换策略(如、处理器能力)、应用场景(批处理或实时响应)、数据规模与访问模式、可LRU)、失效策略(、主动刷新)以及一致性维护缓存命中率是评估维护性和扩展性需求等现代系统通常采用混合策略,根据不同场景动态调LFU TTL缓存有效性的关键指标,它受数据访问模式和缓存策略的影响整,如根据负载情况调整缓存大小,或根据数据特性选择不同的存储和计算策略复杂度下界分析比较模型与决策树表示法与下界证明Ω比较模型是算法分析中的一种重要理论框架,它假设算法只能通过表示法用于描述算法复杂度的下界,即算法在最好情况下也不可Ω比较操作来获取输入元素间的相对顺序信息在这种模型下,算法能比这个复杂度更低下界证明的关键是找到问题本身的内在复杂的执行过程可以表示为一棵决策树,每个内部节点代表一次比较,性,与具体算法无关叶节点代表最终结果除了决策树方法外,下界证明还可以通过信息论方法(如排序问题决策树的高度对应算法在最坏情况下所需的比较次数对于个元需要提供比特的信息)、规约方法(证明一个已知下界的问n logn!素的排序问题,可能的排列数为,因此决策树至少需要个题可以规约到目标问题)或对抗性输入构造(证明对任何算法都存n!logn!叶节点,由此可以推导出排序的比较次数下界为在使其达到下界的输入)等方式进行Ωnlogn尽管比较排序的下界为,但在特殊情况下可以设计出线性时间的排序算法这些算法突破了比较模型的限制,利用了输入ΩnlognOn数据的特殊性质计数排序当排序元素是有限范围内的整数时,通过统计每个元素的出现次数实现排序•On+k基数排序对数字按位排序,复杂度为,其中是位数•Odn+k d桶排序当输入均匀分布时,可以实现接近的期望时间复杂度•On这些算法的存在证明了算法复杂度不仅取决于问题规模,还与问题的特定约束和输入特性密切相关算法实现实践伪代码转实现将抽象算法转换为可执行代码是一项关键技能这一过程需要考虑目标编程语言的特性、数据结构的具体实现以及性能因素好的实践包括选择合适的变量类型和数据结构、分解复杂算法为模块化函数、添加详细注释说明算法步骤和关键决策常见错误与调试算法实现中的常见错误包括数组索引越界、递归终止条件错误、整数溢出、初始化不当和逻辑错误有效的调试策略包括单步跟踪执行过程、使用断言验证中间结果、打印关键状态变量、对比算法执行过程与手动计算结果,以及使用小规模测试用例验证逻辑边界条件处理边界条件是算法正确性的关键挑战常见边界情况包括空输入、单元素输入、最大最/小值输入、满空容器状态等处理边界条件的最佳实践是明确识别所有边界情况、为/每种情况编写专门的测试用例、使用防御性编程风格(如空检查、范围验证),以及在文档中清晰说明处理方式测试用例设计全面的测试是确保算法实现正确性的关键有效的测试用例设计策略包括覆盖所有功能路径、测试边界条件、选择能触发错误的极端情况、使用随机生成的大规模数据测试性能,以及设计能验证算法特定性质(如排序算法的稳定性)的用例自动化测试框架有助于持续验证算法的正确性数据结构选择指南操作需求适用数据结构时间复杂度典型应用快速随机访问数组矩阵计算,快速索引O1频繁插入删除链表动态内存管理/O1*访问栈函数调用,表达式求值LIFO O1访问队列缓冲,任务调度FIFO O1有序数据操作平衡树红黑树等有序映射,范围查询Olog n关键字查找哈希表平均缓存,字典O1优先级管理堆优先队列调度算法,事件处理/Ologn选择合适的数据结构是算法设计的关键步骤对于查询密集型应用,如数据库索引、缓存系统等,应优先考虑支持高效查找的结构,如哈希表平均查找、平衡树查找且保持顺序O1Ologn对于修改密集型应用,如队列系统、动态内存分配器等,应优先考虑支持高效插入删除的结构,如链表插入删除但要已知位置、动态数组支持高效末尾操作在实际工程中,数据规模、内存限制、并发/O1需求和数据访问模式都是重要的考量因素,有时需要组合多种数据结构或设计自定义结构来满足特定需求课程总结与展望核心知识回顾算法设计方法论未来学习方向本课程系统地介绍了数据结构与算法的基掌握了解决计算问题的系统方法,包括如数据结构与算法是探索更高级计算机科学础理论和实践应用,涵盖了算法分析、基何分析问题、选择合适的数据结构、设计领域的基础未来可以深入学习的方向包本数据结构(数组、链表、栈、队列、树、高效算法并进行复杂度分析这种方法论括高级算法(近似算法、随机化算法、图等)、排序与搜索算法、高级算法设计不仅适用于课程中介绍的问题,也能应用在线算法)、计算几何、图像处理算法、方法(分治、动态规划、贪心、回溯)以于解决新的实际挑战算法设计中的权衡机器学习算法、分布式算法以及量子计算及高级数据结构这些知识构成了计算机思想(如时间与空间、简洁性与效率)也算法等这些领域都建立在本课程所学知科学的基础,对后续学习和工作都至关重是解决工程问题的重要思路识的基础上,解决着不同领域的计算挑战要。
个人认证
优秀文档
获得点赞 0