数据结构核心知识点可视化笔记:从线性表到二叉树,一图胜千言

张开发
2026/4/13 19:39:52 15 分钟阅读

分享文章

数据结构核心知识点可视化笔记:从线性表到二叉树,一图胜千言
还在为抽象的数据结构概念头疼吗从线性表到二叉树理解其动态过程往往比记忆静态定义更重要。这时候一个强大的可视化工具能让你事半功倍。推荐试试**图码这个网站它专门为攻克数据结构**和算法难点设计。它提供了超过60种数据结构和算法的交互式动画可视化你可以输入自己的数据或直接上传C/C/Java/Python代码亲眼看到代码是如何一步步运行的。这对于408考研、高校期末考试乃至算法面试的复习都是绝佳的动态笔记和调试利器。其内容紧密贴合国内主流教材和考纲堪称复习神器。别再空想指针如何跳转、堆栈如何压入了去图码亲手操作一下让复杂的逻辑一目了然数据结构核心知识点可视化学习笔记数据结构是计算机存储与组织数据的核心方式其设计直接影响算法效率。本文通过操作步骤状态变化可视化结合代码实现系统梳理线性表、栈、队列、二叉树等核心知识点的底层逻辑同步呈现各操作的“初始状态→执行步骤→最终结果”强化对数据结构动态变化过程的理解为后续算法学习奠定基础。第一章 线性表线性表是由nn≥0个同类型数据元素构成的有限序列是数据结构中最基础的线性结构。按存储方式可分为顺序表和链表顺序表基于连续数组存储链表基于离散节点指针串联后者进一步细分为单链表、双链表、循环单/双链表不同结构的存储连续性与指针指向逻辑差异决定了其操作效率与适用场景的不同。1.1 顺序表数组实现顺序表采用连续数组空间存储数据元素间逻辑关系通过数组下标自然映射。其核心优势为支持随机访问时间复杂度O(1)但插入/删除操作需移动目标位置后的所有元素平均时间复杂度O(n)适用于元素个数相对固定、以查找和修改操作为主的场景。关键操作可视化1. 插入元素index2处插入6数组容量≥6初始data[2,5,8,10,15], length5步骤元素后移data[4]→data[5], data[3]→data[4], data[2]→data[3]插入数据data[2]6更新长度length6。注插入操作后需及时更新表长否则会导致后续操作中元素下标定位错误结果data[2,5,6,8,10,15], length6// 顺序表插入核心代码boolSeqListInsert(intdata[],intlength,intcapacity,intindex,intval){if(index0||indexlength||lengthcapacity){returnfalse;// 插入位置非法或表满}// 元素后移for(intilength;iindex;--i){data[i]data[i-1];}data[index]val;length;returntrue;}2. 删除元素index3处删除8初始data[2,5,6,8,10,15], length6步骤元素前移data[4]→data[3], data[5]→data[4]更新长度length5。结果data[2,5,6,10,15], length51.2 单链表单链表由节点构成每个节点包含数据域与后继指针通过指针串联形成线性结构。其插入/删除操作无需移动元素仅需修改指针指向时间复杂度O(1)前提是已定位操作位置但不支持随机访问需从表头顺序遍历时间复杂度O(n)适用于频繁增删、元素个数动态变化的场景。structListNode{intdata;// 数据域ListNode*next;// 后继指针ListNode(intval):data(val),next(nullptr){}};关键操作可视化1. 插入节点28与47间插入35初始头结点→28→47→79→NULL步骤创建节点newNodenew ListNode(35)指针修改newNode-next28-next35→4728-nextnewNode28→35。结果头结点→28→35→47→79→NULL2. 删除节点删除47初始头结点→28→35→47→79→NULL步骤指针修改35-next47-next35→79释放节点delete 47。结果头结点→28→35→79→NULL3. 单链表逆置三指针法prev、curr、next初始头结点→28→47→79→52→36→NULLprevNULL, curr头结点-next步骤第1次循环nextcurr-next保存47curr-nextprev28→NULLprevcurrcurrnext→结果NULL←28 47→79→52→36→NULL第2次循环nextcurr-next保存79curr-nextprev47→28prevcurrcurrnext→结果NULL←28←47 79→52→36→NULL第3次循环nextcurr-next保存52curr-nextprev79→47prevcurrcurrnext→结果NULL←28←47←79 52→36→NULL第4次循环nextcurr-next保存36curr-nextprev52→79prevcurrcurrnext→结果NULL←28←47←79←52 36→NULL第5次循环nextcurr-next保存NULLcurr-nextprev36→52prevcurrcurrnext→结果NULL←28←47←79←52←36最终头结点-nextprev→头结点→36→52→79→47→28→NULL1.3 双链表双链表节点在单链表基础上增加前驱指针支持双向遍历。插入/删除操作需同时修改前后节点的前驱与后继指针共4处指针修改操作步骤较单链表复杂但在需频繁访问前驱节点的场景中效率更高如双向查找、节点前驱快速定位等。structDListNode{intdata;DListNode*prev;// 前驱指针DListNode*next;// 后继指针DListNode(intval):data(val),prev(nullptr),next(nullptr){}};关键操作可视化28与47间插入35初始头结点↔28↔47↔79↔NULL步骤创建节点newNodenew DListNode(35)指针修改newNode-prev28newNode-next4747-prevnewNode28-nextnewNode。结果头结点↔28↔35↔47↔79↔NULL1.4 循环链表循环单链表尾节点的后继指针指向头结点形成闭合环形结构可从任意节点出发遍历整个链表避免单链表遍历至尾节点后无法继续的问题。循环双链表尾节点后继指针指向头结点头结点前驱指针指向尾节点实现双向循环遍历在表头/表尾插入删除操作中无需单独处理边界条件。第二章 栈栈是一种遵循“先进后出”LIFO规则的线性结构仅允许在栈顶进行插入push与删除pop操作辅助操作包括获取栈顶元素top与判断栈空isEmpty。栈的操作限制使其具有明确的元素进出顺序在表达式求值、函数调用栈、括号匹配等场景中广泛应用。2.1 顺序栈数组实现顺序栈基于数组实现通过栈顶指针top标记栈顶元素位置初始时top-1表示栈空。入栈操作需先判断栈满再执行top后存入元素出栈操作需先判断栈空再取出top位置元素后执行top–。顺序栈操作效率高但容量固定栈满时需进行扩容处理。关键操作可视化1. 入栈push(4)初始data[1,2,3], top2步骤toptop3data[top]4结果data[1,2,3,4], top32. 出栈pop()初始data[1,2,3,4], top3步骤取出data[top]top–top2结果data[1,2,3,4], top2栈顶为32.2 链栈链表实现链栈基于单链表实现栈顶指针top指向链表头节点无固定容量限制。入栈操作通过创建新节点并将其作为新的头节点实现出栈操作通过删除头节点并更新top指针实现。链栈无需预先分配内存避免溢出问题但指针操作存在少量额外开销。structStackNode{intdata;StackNode*next;StackNode(intval):data(val),next(nullptr){}};关键操作可视化1. 入栈push(4)初始top→[3]→[2]→[1]→NULL步骤创建节点newNodenew StackNode(4)指针修改newNode-nexttoptopnewNode。结果top→[4]→[3]→[2]→[1]→NULL2. 出栈pop()初始top→[4]→[3]→[2]→[1]→NULL步骤保存节点temptop指针修改toptop-next释放节点delete temp。结果top→[3]→[2]→[1]→NULL栈对比总结结构类型实现方式容量限制操作效率适用场景顺序栈数组固定易溢出O(1)数组下标操作元素数量已知如表达式求值链栈单链表无动态扩容O(1)指针修改元素数量未知如函数调用栈第三章 队列队列是遵循“先进先出”FIFO规则的线性结构元素插入EnQueue在队尾进行元素删除DeQueue在队头进行辅助操作包括获取队头元素front与判断队空isEmpty。队列的特性使其适用于任务调度、缓冲处理、广度优先搜索BFS等需按顺序处理数据的场景。3.1 顺序队列普通普通顺序队列基于数组实现通过队头指针front标记队头位置队尾指针rear标记队尾下一个位置初始时front与rear均为0。入队操作使rear后移出队操作使front后移但存在“假溢出”问题——当rear达到数组容量上限时即使数组前部有空余空间也无法入队空间利用率低。操作轨迹初始front0, rear0, data[,,,]EnQueue(1)data[1]1, rear2→front0, rear2, data[,1,,*]EnQueue(2)data[2]2, rear3→front0, rear3, data[,1,2,]DeQueue()返回data[1]1, front2→front2, rear3, data[,,2,*]假溢出rear3达容量数组前2位空但无法入队。3.2 循环队列解决假溢出循环队列通过将数组空间逻辑视为环形结构解决普通顺序队列的假溢出问题。front与rear指针通过取模运算%capacity循环移动队空条件为frontrear队满条件为(rear1)%capacityfront预留一个空闲位置以区分队空与队满空间利用率与操作效率均优于普通顺序队列。操作轨迹capacity5初始front0, rear0, data[,,,,*]EnQueue(1)rear(01)%51, data[1]1→front0, rear1, data[,1,,,]EnQueue(2)rear(11)%52, data[2]2→front0, rear2, data[,1,2,,*]DeQueue()front(01)%51→front1, rear2, data[,,2,,]EnQueue(3)rear(21)%53, data[3]3→front1, rear3, data[,,2,3,*]EnQueue(4)rear(31)%54, data[4]4→front1, rear4, data[,,2,3,4]EnQueue(5)rear(41)%50, (01)%51front→队满无法入队。3.3 链队列链队列基于单链表含头节点实现front指针指向头节点rear指针指向队尾节点初始时均指向头节点。入队操作在队尾创建新节点并更新rear指针出队操作删除头节点的后继节点并更新front指针若队空需将rear也指向头节点。链队列无容量限制不存在溢出问题适用于元素个数不确定的场景。关键操作可视化EnQueue(3)初始front→头结点→[1]→[2]→rear指向[2]步骤创建节点newNodenew ListNode(3)指针修改rear-nextnewNoderearnewNode。结果front→头结点→[1]→[2]→[3]→rear指向[3]队列对比总结结构类型实现方式溢出问题空间利用率适用场景普通顺序队列数组假溢出低简单场景、元素数量固定少用循环队列数组无留一空位中元素数量已知、需高效处理如缓存队列链队列单链表无动态扩容高任务数量不确定如服务器请求队列第四章 二叉树二叉树是一种非线性数据结构每个节点最多拥有两个子树左子树与右子树且子树具有左右次序。二叉树通常采用二叉链表存储每个节点包含数据域、左指针指向左子树与右指针指向右子树其层级结构使其在数据检索、排序、表达式树构建等领域具有重要应用。4.1 二叉链表遍历二叉树遍历是按特定顺序访问所有节点且每个节点仅访问一次的操作是二叉树后续操作的基础。根据访问根节点的时机不同分为前序根→左→右、中序左→根→右、后序左→右→根三种深度优先遍历以及按层从上到下的广度优先遍历层序遍历。示例树结构1为根左子树2左4、右5右子树3遍历轨迹前序根→左→右1→2→4→5→3中序左→根→右4→2→5→1→3后序左→右→根4→5→2→3→1层序按层从上到下1→2→3→4→54.2 最优二叉树哈夫曼树哈夫曼树是带权路径长度WPL最短的二叉树其中WPL为所有叶子节点的权值与路径长度根节点到该节点的边数的乘积之和。构建规则为每次选取两个权值最小的节点合并为一个新节点新节点权值为两节点权值之和重复此过程直至仅剩一个节点根节点。哈夫曼树是哈夫曼编码的核心用于实现数据压缩。构建轨迹权重2,3,5,7初始[2],[3],[5],[7]合并235[5(新)],[5],[7]合并5(新)510[10(新)],[7]合并10717[17(根)]WPL2×33×35×27×1324.3 线索链表中序线索化线索链表通过利用二叉链表中的空指针n个节点含n1个空指针将其改为指向节点前驱或后继的线索实现二叉树的线性遍历。中序线索化是按中序遍历顺序设置线索空左指针指向该节点的中序前驱空右指针指向该节点的中序后继可避免递归或栈辅助提高遍历效率。线索化轨迹示例树中序4→2→5→1→34的右指针→2后继2的左指针→4前驱5的右指针→1后继5的左指针→2前驱1的左指针→5前驱3的右指针→NULL二叉树核心应用场景遍历文件系统目录遍历、表达式树求值哈夫曼树数据压缩如ZIP压缩线索链表高效遍历大型二叉树如数据库索引树

更多文章