数据结构 | 学习与刷题笔记
文章平均质量分 81
以课堂学习与练习实战为线索,从线性表、栈队列等基础结构到进阶内容,逐步梳理核心逻辑,附手写代码实现,夯实算法思维与编程能力。
DreamLuminous
哈喽~欢迎来到我的小天地 我是大二软件工程生,深耕嵌入式方向,开博只为真诚记录学习与生活,沉淀美好与成长。这里会扎实分享 C 语言干货与实战案例,后续也将持续更新 C++、Linux 及嵌入式硬件的学习笔记;同时也会记录摄影剪辑的创作心得,定格生活里的美好瞬间。不追流量,不刻意堆砌,每一篇都是用心的沉淀,愿这里能成为技术同好交流进阶的小站,也能分享细碎的生活温暖,盼与你一起交流成长,不负热爱️
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
数据结构-排序(五):计数排序与排序专题阶段总结|从外部归并到线性排序,再看算法边界与选型
本文是排序专题第五篇,属于排序阶段阶段性总结。讲解计数排序非比较排序原理,通过最值偏移处理负数,剖析时间复杂度O(N+R)与值域R带来的适用局限,说明基础版本稳定性问题。延伸介绍外部归并排序、三路快排、内省排序、基数、桶排序思想。汇总已学排序算法指标对比,分析各算法适用场景。代码实现独立CountSort项目,并接入综合测试工程,依托十万数据完成计时与正确性校验。原创 2026-09-16 23:49:54 · 386 阅读 · 0 评论 -
数据结构-排序(四):归并排序详解|递归分治 + 非递归迭代 + gap 边界处理
本文是排序专题第四篇,讲解归并排序的递归分治与非递归迭代两种实现。剖析闭区间 [begin,mid] 与 [mid+1,end] 划分要点,说明需要 O (N) 辅助数组的原因。重点解析自底向上 gap 迭代逻辑,处理数组末尾两组缺失、右组不完整两类边界。对比递归与非递归本质,区分归并与快排的设计差异,讲解稳定性细节。代码先搭建独立 MergeSort 工程,再接入综合排序框架,依托十万随机数据完成计时与有序校验。原创 2026-09-13 23:16:02 · 361 阅读 · 0 评论 -
数据结构-排序(三):快速排序进阶|挖坑法、双指针交换与手动栈非递归实现
本文是排序专题第三篇,深入拆解快速排序的可组合框架:基准选择、Partition 划分、子区间调度。对比讲解挖坑法、双指针交换两种 partition 实现,剖析二者基准保存、元素移动的差异。实现手动栈替代函数递归的非递归版本,规避递归栈溢出风险。所有实现统一复用三数取中和小区间插入优化,接入十万级随机数据性能测试,保证对比公平。帮助理解模块化思想,认识递归与迭代的转换思路。原创 2026-09-11 00:37:06 · 124 阅读 · 0 评论 -
数据结构 - 排序(二):快速排序从错误初版到优化版|双指针划分 + 三数取中 + 小区间插入优化
本文为排序专题第二篇,讲解快速排序从错误雏形到工程优化版本的完整演进。演示双指针交换划分实现,剖析初版基准存值、越界等典型bug,修复后引入递归完成分治排序。介绍三数取中解决有序数组性能退化,小区间切换插入排序降低递归开销。梳理时间、空间复杂度与稳定性,接入统一测试工程,十万数据与其他排序横向对比,帮助理解递归、双指针与工程优化思想。原创 2026-09-08 23:55:22 · 281 阅读 · 0 评论 -
数据结构-排序(一):基础排序算法横向对比|冒泡、插入、希尔、堆与双向选择,详解二分 / Knuth 增量
本文为排序专题开篇,在统一工程中实现冒泡、直接插入、双向循环选择、堆排序,以及二分、Knuth两种增量的四版希尔排序,使用十万随机数组做公平性能对比。讲解希尔排序分组预排序思想,辨析三重分组与二重交叉实现差异,剖析双向选择排序下标修正的易错坑点。梳理各算法时间、空间复杂度与稳定性,借助实测直观展现O(N²)与O(NlogN)的性能差距,为后续快排、归并排序学习打下基础。原创 2026-09-07 23:58:35 · 393 阅读 · 0 评论 -
二叉树专题(一):从递归判断到子树匹配与遍历建树
本文从基础接口进入二叉树刷题实战,通过单值二叉树、相同的树、另一棵树的子树、前序遍历返回数组、前序串建树五道经典题目,逐层拆解递归判断逻辑。文中对比 && 与 || 的适用场景、双树同步递归写法、结果收集型递归实现,复盘递归返回值丢失、参数错误等典型错题,帮你从 “会写递归” 到 “写对递归”,建立系统化的二叉树递归解题思维。原创 2026-08-29 00:15:48 · 218 阅读 · 0 评论 -
数据结构-二叉树(六):BFS层序遍历与完全二叉树判断|复用链式队列 + (N_0=N_2+1) 性质证明
本文介绍复用已有链式队列实现二叉树 BFS 层序遍历,新增完全二叉树判断接口。基于现有工程增量开发,不改动原有代码,读者只需少量修改头文件、追加函数实现即可快速使用。文中对比数组模拟队列与链式队列两种层序实现,解析完全二叉树 BFS 判定逻辑,同时推导经典二叉树性质(N_0=N_2+1),结合两道典型例题讲解完全二叉树叶子结点计算,帮你打通队列与二叉树的联动,理解 BFS 思想的实际工程应用。原创 2026-09-02 01:20:06 · 333 阅读 · 0 评论 -
数据结构-二叉树(五):查找、销毁与前序序列建树
本文承接链式二叉树的遍历与统计基础,补充三个核心接口实现:递归查找目标结点、二级指针后序销毁整棵树、基于带 #标记的前序序列还原二叉树。文中拆解每个接口的递归逻辑,详解二级指针销毁的必要性、递归返回值不可丢弃、下标指针替代静态变量等关键细节,梳理三种典型递归模式,帮你夯实二叉树递归底层逻辑,避开 C 语言指针与递归的高频踩坑点。原创 2026-08-28 23:57:52 · 375 阅读 · 0 评论 -
数据结构-二叉树(四):链式结构与递归遍历|前中后序 + 层序遍历 + 结点统计与高度
本文开启二叉树链式结构的学习,对比数组存储的缺陷,讲解二叉树结点的指针式设计。重点拆解前序、中序、后序三种深度优先递归遍历,以及基于队列的层序广度优先遍历。实现结点总数、叶子结点、树高度、第 K 层结点数等经典递归接口,对比多种计数写法,点明递归重复计算的性能陷阱,帮助理解二叉树分治递归的核心思维,配套完整可运行 C 语言代码。原创 2026-08-27 23:25:43 · 382 阅读 · 0 评论 -
数据结构-二叉树(三):堆复杂度证明与 Top-K 问题|错位相减推导 + 海量数据内存优化
本文围绕二叉堆展开,针对很多同学的疑惑:堆单次调整为 O (logN),为什么向上、向下两种建堆方式复杂度却截然不同。借助满二叉树模型,使用错位相减完成严谨数学推导,拆解两者性能差距的根源。同时结合经典 Top‑K 问题,模拟内存不足的海量数据场景,讲解小根堆筛选前 K 大元素的原理,并给出可直接运行的 C 语言流式测试代码,附带自动化结果校验,帮助理解堆在工程中的实际价值。原创 2026-08-26 23:42:45 · 357 阅读 · 0 评论 -
数据结构‑二叉树(二):二叉堆从零实现|Heap结构设计 + 建堆优化 + 堆排序深度解析
本文承接二叉树专题,深入解析数据结构中的核心结构——二叉堆。从完全二叉树的数组映射出发,结合C语言实现完整堆接口,详细讲解结构体设计、指针传参原因、向上调整与向下调整原理,以及大小根堆切换方法。通过图解对比向上建堆与向下建堆,分析O(NlogN)与O(N)复杂度差异,并深入拆解堆排序、“降序建小堆,升序建大堆”的核心思想。最后结合测试案例,总结Top-K、优先级队列等实际应用与常见踩坑。原创 2026-08-24 00:27:25 · 349 阅读 · 0 评论 -
数据结构-二叉树(一):树的基础概念与二叉树核心结构
本文是二叉树数据结构的入门指南,首先介绍了树的基本概念和核心特点,包括根节点、子节点、层次等术语。然后重点讲解了二叉树的特殊结构和两种常见类型:满二叉树和完全二叉树。文章详细阐述了二叉树的五大核心性质,特别是完全二叉树在顺序存储中的父子节点定位公式。最后对比了顺序存储和链式存储的适用场景,并引入堆结构的概念及其应用。全文为后续深入学习二叉树算法奠定了理论基础,强调理解底层原理而非机械记忆代码。原创 2026-08-20 23:59:05 · 312 阅读 · 0 评论 -
栈和队列专题(四):LeetCode 232. 用栈实现队列|双栈分工 + 按需迁移 + 摊还 O(1)
本文讲解LeetCode 232「用栈实现队列」的经典双栈方案,明确inStack负责入队、outStack负责队头操作的分工模式,重点解析“仅outStack为空时整体迁移”的核心规则,以及pop复用peek的代码优化写法,深入拆解摊还O(1)的复杂度原理。文中横向对比了225、622两道同类题的差异,体现栈模块的工程复用价值。至此栈队列三道核心实现题梳理完毕,后续将开启二叉树专题,栈队列经典应用题也会继续跟进练习。原创 2026-08-20 01:10:05 · 347 阅读 · 0 评论 -
栈和队列专题(三):LeetCode 622. 设计循环队列|数组环形复用 + front/rear 边界详解
本文详细讲解了循环队列的设计与实现,重点分析了如何利用数组实现环形结构以避免空间浪费。文章首先通过示例说明普通数组队列的"假溢出"问题,然后提出循环队列的解决方案。核心内容包括:1. 采用牺牲一个存储位置的方案区分队列空满状态;2. 明确front和rear指针的语义(front指向队首元素,rear指向下一个可插入位置);3. 使用取模运算实现下标的循环移动。文章完整实现了LeetCode 622题要求的全部接口,并分析了各种边界情况,特别是队尾元素的获取方法。最后对比了数组实现与链式原创 2026-08-20 00:56:09 · 501 阅读 · 0 评论 -
栈和队列专题(二):LeetCode 225. 用队列实现栈 | 双链表队列从零实现 + 完整做题复盘
本文介绍了如何使用两个队列实现栈的基本操作(push、pop、top、empty)。通过维护一个关键不变量——始终保持一个队列存数据、另一个为空,解决了队列FIFO与栈LIFO的特性矛盾。核心思路是在pop和top操作时,将前n-1个元素转移到空队列,保留最后一个元素作为栈顶。文章详细对比了初始实现与优化写法,分析了时间复杂度(push为O(1),pop/top为O(N)),并指出常见错误(如队列清空时指针处理不当)。最后提及单队列实现方案,强调数据结构特性转换的算法价值。代码已开源。原创 2026-08-19 00:42:32 · 356 阅读 · 0 评论 -
栈和队列专题(一):LeetCode 20. 有效的括号
本文介绍了使用栈数据结构解决括号匹配问题的经典方法。题目要求判断一个仅包含括号的字符串是否有效,即所有括号都能正确闭合且顺序匹配。解题思路是利用栈的LIFO特性,遇到左括号压栈,遇到右括号与栈顶元素匹配,匹配成功则弹栈,最终检查栈是否为空。文章提供了C语言手动实现顺序栈的完整代码,包括初始化、入栈、出栈等操作,以及C++使用STL stack的简洁实现。关键点包括正确处理边界条件、内存管理和时间复杂度分析(O(n)),并总结了常见错误。通过此题可深入理解栈的基本原理和应用场景。原创 2026-08-16 23:33:14 · 193 阅读 · 0 评论 -
数据结构-栈和队列(二):C语言链式队列完整实现|结构设计 + 代码 + 复盘 + size 成员深度解析
本文详细介绍了链式队列的实现原理与优化技巧。通过对比顺序表实现队列的缺陷,阐明单链表+尾指针方案的高效性(入队/出队O(1))。重点解析了front/rear双指针与size成员的设计价值,后者可将长度查询从O(N)优化至O(1)。文章提供模块化代码实现,包含初始化、入队、出队等核心操作,特别强调边界处理(空队列和单节点场景)。附有典型错误案例复盘和完整测试用例,测试覆盖队列各种状态转换。所有代码已开源,采用头文件与实现文件分离的规范写法,可直接编译调试。原创 2026-08-17 23:36:47 · 330 阅读 · 0 评论 -
数据结构-栈和队列(一):C语言手写顺序栈|两种 top 约定 + 接口封装详解
栈是操作受限的线性表,遵循后进先出 LIFO 原则。本文使用 C 语言实现动态顺序栈,重点讲解两种主流 top 标记约定:`top=0`指向待插入位置与教材常用`top=-1`指向栈顶元素。提供两套完整源码,头文件接口统一,编译需二选一。对比两套实现的边界条件,梳理入栈、出栈易错点,讲解接口封装思想,说明应当调用封装函数而非直接访问结构体成员。配套测试用例验证接口,理解栈扩容逻辑,为后续队列学习铺垫基础。原创 2026-08-15 21:50:49 · 729 阅读 · 0 评论 -
数据结构基础篇(二):顺序表与链表全方位对比|从内存布局到 CPU 缓存理解底层差异
顺序表和链表的本质差异在于内存连续性。顺序表(动态数组)物理内存连续,支持O(1)随机访问,CPU缓存利用率高,但扩容需拷贝;链表节点离散存储,插删灵活但访问需遍历,且内存碎片和缓存不友好导致实际性能较差。虽然链表的“插删O(1)”需已知节点位置,但多数场景下顺序表因缓存和遍历优势更受青睐。理解硬件层面的内存与缓存机制,才能在实际工程中选择合适的数据结构,例如栈优先用数组实现。数据结构的选择本质是时间、空间与灵活性的权衡。原创 2026-08-15 21:20:03 · 475 阅读 · 0 评论 -
数据结构基础篇(一):时间与空间复杂度|时间/空间复杂度 + 两道力扣练习 + 二分查找复盘
本篇记录数据结构学习进入复杂度分析阶段后的学习复盘。从时间复杂度、空间复杂度的基本概念出发,结合 LeetCode「消失的数字」「旋转数组」两道题,分析不同解法背后的效率差异;同时复习二分查找,通过区间开闭、循环条件和边界更新的对应关系,进一步理解 O(logN) 算法的实现细节。本文不仅总结复杂度分析方法,也记录从“代码能跑”到“关注效率”的思维转变。原创 2026-08-11 20:45:10 · 425 阅读 · 0 评论 -
数据结构-双向循环链表
本文记录了作者实现带哨兵位的双向循环链表的过程与踩坑经验。文章重点不在于展示完美代码,而是通过实际开发中遇到的五个典型问题(打印错误、指针传参错误、删除逻辑错误、误删哨兵节点、销毁函数崩溃),逐步分析调试过程。每个问题都配有详细解释和修复后的正确代码,最终形成功能完整的实现。作者强调理解指针操作和链表连接关系的重要性,并分享了从"代码能跑"到"代码规范"的优化过程,附有完整代码仓库链接。原创 2026-08-10 01:25:12 · 408 阅读 · 0 评论 -
C 语言集中实践全记录:顺序表 + 单链表原理实现与通讯录项目实战【附可运行源码】
本仓库为C语言数据结构线性存储结构的专项学习项目,完整记录了从基础概念到实际应用的开发流程。主要内容包括:1)动态顺序表的全套接口实现与通讯录管理系统开发,涵盖初始化、增删改查、扩容销毁等核心功能;2)单链表的基础操作实现与对比分析;3)真实项目开发中的问题调试经验,如输入缓冲区处理、字符串匹配优化等。项目提供完整源码、可执行文件及详细学习记录,特别适合C语言初学者系统学习数据结构。通过本项目可掌握线性表的两种存储方式差异,提升工程化编程能力。原创 2026-07-14 00:07:47 · 270 阅读 · 0 评论 -
单链表专题(四)-刷题复盘篇-LeetCode 138 随机链表复制|原地拷贝法突破复杂指针操作
本文详细解析了LeetCode138「随机链表的复制」这道经典链表题目。作者从单链表的基础操作出发,分析了加入random随机指针后带来的挑战,重点介绍了原地拷贝法的三步实现:1)在原节点后插入拷贝节点建立映射;2)利用映射关系修正random指针;3)拆分混合链表为独立的两条链表。文章提供了完整的AC代码和关键细节分析,包括指针操作的常见错误和复杂度分析,特别强调了链表操作中保持结构清晰的重要性。该解法时间复杂度O(N),空间复杂度O(1),通过巧妙利用原链表结构建立映射关系,避免了哈希表的额外空间消耗。原创 2026-08-14 23:42:35 · 554 阅读 · 0 评论 -
单链表专题(三)-刷题复盘篇:从快慢指针到环形链表 II 数学推导
本文复盘单链表四道经典面试题:倒数第 k 个节点、回文链表、相交链表与环形链表 II,系统梳理定距双指针、快慢指针、原地反转和长度对齐等核心思路,并分析时间、空间复杂度。重点结合手写笔记推导 Floyd 判环中“为何必然相遇”与“为何第二次相遇即为入环点”,最后补充通用步长与贝祖定理拓展,帮助从会写代码进一步理解算法原理。原创 2026-08-13 23:18:14 · 609 阅读 · 0 评论 -
单链表专题(二)-刷题复盘篇:四道经典题踩坑记录+多思路对比
这篇文章总结了作者在刷链表和数组相关算法题时的经验与心得。四道题目分别是合并有序数组、反转链表、合并有序链表和分割链表,均围绕双指针思想展开。作者详细记录了每道题的解题思路、踩坑点和优化过程,如数组合并需从后往前操作避免覆盖、反转链表需先保存后继节点防止断链、分割链表后需切断尾部避免成环等。文章强调算法不是越花哨越好,思路朴素但边界清晰的写法往往更实用,并总结了链表题的通用避坑口诀:修改指针前保存后继、善用虚拟头节点、重组后处理尾部指针等。通过反复实践,作者逐渐建立起对指针操作的直觉,为后续进阶题打下基础。原创 2026-08-06 00:47:15 · 341 阅读 · 0 评论 -
单链表专题(一)-应用篇:三道经典题吃透删除、反转与快慢指针
本文系统讲解单链表三大经典问题:移除元素、反转链表和查找中点。针对移除元素提出尾插法和虚拟头节点两种解法;反转链表详细解析三指针迭代和递归两种实现;查找中点重点分析快慢指针算法。文章强调单链表操作的核心在于指针修改和边界处理,总结出通用解题框架:处理头节点变化需采用新链表或虚拟头节点、修改指针前必须保存后继节点、必须验证空链表等边界场景。通过这三道基础题的深度剖析,帮助读者掌握单链表的核心操作与解题思路,为后续进阶题目打下坚实基础。原创 2026-07-13 23:00:07 · 406 阅读 · 0 评论 -
数据结构 - 单链表(二):单链表进阶操作
本文详细讲解单链表的进阶操作,包括指定位置后插/前插、删除指定节点/后继节点以及链表销毁等。核心要点包括:1.插入操作必须遵循"先连后继再改前驱"的铁则,避免断链;2.前插和删除当前节点需遍历查找前驱节点;3.删除操作需先保存节点地址再释放内存;4.销毁链表时要逐个释放节点并将头指针置NULL。文章通过代码示例和测试案例,分析各类操作的时间复杂度(后插O(1)、前插O(n)),并总结链表操作的通用方法论,强调指针操作顺序和边界条件处理的重要性,为后续学习更复杂数据结构奠定基础。原创 2026-06-13 11:54:15 · 420 阅读 · 0 评论 -
数据结构 - 单链表(一):单链表基础操作
本文详细讲解了C语言单链表的基础操作实现,包括头插、尾插、头删、尾删和查找等核心功能。通过结构体定义、辅助函数封装和具体操作实现三个层面,剖析了单链表的设计思路与编码要点。重点阐述了二级指针在头插/头删中的必要性、尾操作的前驱节点处理、边界条件判断等关键问题,并提供了通用编程方法论:二级指针判断法则、遍历临时指针使用、删除先保留原则等。文中包含完整测试代码和运行结果,帮助读者系统掌握单链表的实现原理和工程实践技巧,为后续学习更复杂的链表操作奠定基础。原创 2026-06-13 11:44:16 · 428 阅读 · 0 评论 -
C 语言通讯录补坑篇:终版遗留 Bug 修复,解决修改姓名输入错乱问题
本文是C语言通讯录终版的补坑记录,针对5月25日测试发现的**修改姓名输入错乱Bug**进行复盘与修复。问题根源为输入工具函数重复清空缓冲区,导致用户输入被意外吞噬。文中拆解错误逻辑,重构输入函数,移除冗余缓冲区清理代码,同时通过备份结构体原始数据、添加const修饰优化代码规范性。经多组用例测试,功能恢复正常。本次问题也总结了C语言`scanf`与`fgets`混用的缓冲区处理经验,为新手规避同类输入问题提供参考。原创 2026-05-28 14:38:38 · 416 阅读 · 0 评论 -
C 语言通讯录(终版)|新手踩坑全总结 + 最终可运行代码博客简介
本文介绍了C语言通讯录项目的终版实现,通过三篇系列文章完整闭环:基础版实现增删查改和文件存储,优化版修复核心bug并新增多条件查找等功能,终版进行代码规范重构和全bug修复。项目采用标准C语言分文件写法,包含头文件声明、功能实现和主程序入口。重点解决了输入异常处理、回车跳过修改、重名校验等常见问题,新增了自动保存、多条件查询等实用功能。通过该项目,开发者可以掌握结构体使用、顺序表实现、文件操作等C语言核心技能,以及调试技巧和工程组织方式。原创 2026-05-21 16:02:18 · 221 阅读 · 0 评论 -
数据结构 - 线性表(四):C 语言通讯录优化升级全记录(踩坑 + 思考)
本文记录了作者对基础版通讯录系统的优化过程。针对输入汉字死循环、修改体验差、查找功能单一等痛点,作者按照优先级逐步优化:首先解决输入汉字导致的死循环问题,通过清理输入缓冲区实现;其次改进修改功能,支持回车跳过无需修改的字段;然后扩展查找功能,支持按电话/地址多条件查找;最后优化性别输入,支持0/1快捷输入。文章详细记录了每个问题的分析过程、解决方案和代码实现,包括输入缓冲区处理、fgets函数应用、字符串比较优化等关键技术点。通过这一系列优化,通讯录系统从基础功能升级为实用工具,大幅提升了用户体验。原创 2026-05-21 15:33:13 · 648 阅读 · 0 评论 -
数据结构 - 线性表(三):基于顺序表实现 C 语言通讯录(基础功能篇)
本文记录了基于动态顺序表实现简易通讯录的开发过程。作者详细还原了开发中遇到的典型问题:头文件循环包含(通过前向声明解决)、数据类型不匹配导致乱码(修正scanf格式符)、文件不存在导致崩溃(增加错误处理)、输入缓冲区问题等。最终实现的基础版通讯录支持联系人增删改查和数据持久化功能,但仍存在输入校验不足、代码冗余、用户体验差等问题。文章总结了新手常见错误,如头文件组织、数据类型匹配、文件操作容错等关键点,为后续优化版本奠定了基础。原创 2026-05-21 14:42:37 · 444 阅读 · 0 评论 -
数据结构 - 线性表(二):动态顺序表进阶接口实现
本文详细介绍了动态顺序表的进阶实现,重点讲解了四个核心接口:指定位置插入(SLInsert)、指定位置删除(SLErase)、按值查找(SLFind)和按位置修改(SLModify)。文章通过代码示例展示了各接口的实现原理,特别强调了边界条件的处理(如插入/删除时的下标校验)和常见错误(如元素移动方向错误)。同时提供了完整的多文件实现方案,包括头文件声明、功能实现和测试用例。最后总结了顺序表实现的关键要点,包括断言防护、元素移动规则和工程化编码规范,为后续基于顺序表的实战项目(如通讯录系统)打下基础。原创 2026-05-19 18:48:01 · 501 阅读 · 0 评论 -
数据结构-线性表(一)
本文分享了作者二刷数据结构顺序表的学习心得与实践经验。文章首先分析了重学顺序表的原因:第一次学习时C语言基础不扎实,导致理解不透彻。作者通过手写代码、调试排错、优化封装的方式,实现了动态顺序表的核心功能,包括初始化、扩容、头尾增删等操作。文中详细记录了5个典型Bug及修复过程,重点介绍了通用打印函数的优化实现,通过宏定义使代码适配不同数据类型。最后展示了多文件工程化拆分方案和完整代码实现,并制定了后续学习计划。作者强调数据结构学习要注重基础、手写代码和工程规范,避免盲目追求进度。原创 2026-05-16 20:40:33 · 455 阅读 · 0 评论
分享