[{"data":1,"prerenderedAt":1908},["ShallowReactive",2],{"blog-taxonomies":3,"blog-stats":507,"post-数据结构\u002F2025-09-29-数据结构-树":1083},[4,11,16,21,25,29,36,39,44,47,52,58,63,66,71,76,80,84,87,93,96,101,105,110,113,117,122,127,132,136,141,143,146,151,155,157,162,165,169,173,176,179,183,186,190,193,197,200,205,208,211,214,219,222,228,234,237,239,245,249,253,256,260,266,271,276,281,283,287,290,293,298,301,304,306,308,311,314,316,318,321,327,332,337,342,347,352,354,356,358,361,365,367,369,371,374,376,378,381,386,390,393,396,400,404,407,411,413,415,417,421,423,425,428,431,433,435,437,439,441,443,446,448,450,454,456,459,461,463,465,467,469,471,473,477,483,486,488,491,493,495,497,499,501,503,505],{"category":5,"tags":6},"笔记",[7,8,9,10],"QQ","插件","LiteLoader","美化",{"category":12,"tags":13},"其他",[14,15,10],"博客","IP签名",{"category":17,"tags":18},"杂谈",[19,20],"互联网","观点",{"category":5,"tags":22},[14,23,24],"GitHub","数据可视化",{"category":5,"tags":26},[14,27,28],"访问统计","不蒜子",{"category":30,"tags":31},"工具",[32,33,34,35],"Python","爬虫","选课脚本","广州大学",{"category":5,"tags":37},[38,5],"数学分析",{"category":40,"tags":41},"算法",[42,40,43],"数据结构","线性表",{"category":40,"tags":45},[42,46],"复习",{"category":5,"tags":48},[49,50,51],"高等代数","线性代数","知识点",{"category":5,"tags":53},[14,54,55,56,57],"Typora","PicGo","图床","Markdown",{"category":30,"tags":59},[60,61,62],"Jupyter","工具配置","中文",{"category":30,"tags":64},[65,61,10],"VSCode",{"category":30,"tags":67},[68,69,70,35],"路由器","OpenWrt","校园网",{"category":12,"tags":72},[73,74,75],"网络协议","Wireshark","DEVP2P",{"category":5,"tags":77},[73,74,78,79],"Lua","解码器",{"category":5,"tags":81},[82,5,83],"常微分方程","数学",{"category":5,"tags":85},[86,5,83],"概率论",{"category":30,"tags":88},[89,90,91,92],"Docker","WSL","Windows","磁盘清理",{"category":30,"tags":94},[32,33,95,35],"课程表",{"category":5,"tags":97},[14,98,99,100],"Hexo","Gitalk","评论系统",{"category":5,"tags":102},[14,103,98,104],"Obsidian","写作工具",{"category":12,"tags":106},[107,108,109],"课题研究","泊松分布","参数估计",{"category":12,"tags":111},[107,108,109,112],"组会",{"category":12,"tags":114},[109,115,108,116],"IM模型","统计学",{"category":17,"tags":118},[119,120,121],"软考","网络规划","信息系统项目管理",{"category":30,"tags":123},[124,125,126],"Arch Linux","AppImage","Linux",{"category":5,"tags":128},[129,130,131],"编程语言","计算机科学","内存管理",{"category":5,"tags":133},[134,135],"Canvas","前端",{"category":5,"tags":137},[14,138,139,140],"GitHub Actions","Vite","部署",{"category":5,"tags":142},[135],{"category":5,"tags":144},[135,145],"系统设计",{"category":5,"tags":147},[135,148,149,150],"安全","XSS","CSRF",{"category":152,"tags":153},"项目",[134,154],"PixiJS",{"category":152,"tags":156},null,{"category":40,"tags":158},[42,159,160,161],"栈","队列","JavaScript",{"category":40,"tags":163},[42,164,161],"哈希表",{"category":5,"tags":166},[167,161,168],"ES6","Set",{"category":40,"tags":170},[40,171,172],"动态规划","背包问题",{"category":40,"tags":174},[40,175],"滑动窗口",{"category":40,"tags":177},[42,178,161],"链表",{"category":40,"tags":180},[40,181,161,182],"ACM","面试",{"category":40,"tags":184},[40,161,185],"数据类型转换",{"category":40,"tags":187},[42,188,178,189],"顺序表","TypeScript",{"category":5,"tags":191},[135,154,134,192],"渲染",{"category":5,"tags":194},[135,195,134,196],"富文本编辑","wangEditor",{"category":40,"tags":198},[199,40,178],"力扣",{"category":5,"tags":201},[202,203,204,91],"DNS","加密","网络安全",{"category":5,"tags":206},[135,207],"Axios",{"category":5,"tags":209},[135,207,189,210],"接口封装",{"category":5,"tags":212},[135,213,145],"JWT",{"category":152,"tags":215},[134,216,217,154,218],"画布","React","项目开发",{"category":17,"tags":220},[221],"日志",{"category":5,"tags":223},[224,225,226,227],"Neo4j","图数据库","中心度分析","PageRank",{"category":12,"tags":229},[230,231,232,233],"论文","机器学习","随机森林","保险欺诈",{"category":5,"tags":235},[236],"人工智能",{"category":5,"tags":238},[231,40,32],{"category":12,"tags":240},[241,242,243,244],"共识算法","最长链","区块链","算法设计",{"category":5,"tags":246},[161,247,248,135],"闭包","作用域",{"category":5,"tags":250},[14,138,251,252],"RSS","自动化",{"category":30,"tags":254},[89,90,91,255],"安装",{"category":30,"tags":257},[258,91,259],"MSYS2","开发环境",{"category":5,"tags":261},[262,263,264,265],"团队协作","Git","Commit规范","代码审查",{"category":30,"tags":267},[268,269,270],"oh-my-posh","终端美化","CLI",{"category":5,"tags":272},[273,274,275],"上下文工程","Agent","RAG",{"category":5,"tags":277},[278,279,280],"前端工程化","技术选型","工程基建",{"category":5,"tags":282},[275],{"category":5,"tags":284},[285,286],"SDD","规格驱动开发",{"category":5,"tags":288},[289],"neovim",{"category":5,"tags":291},[292],"技术写作",{"category":5,"tags":294},[295,32,296,89,297],"FastAPI","后端","工程实践",{"category":152,"tags":299},[274,300],"Harness Engineering",{"category":5,"tags":302},[303],"RFC",{"category":152,"tags":305},[274,300,275],{"category":152,"tags":307},[274],{"category":40,"tags":309},[199,40,161,310],"两数之和",{"category":40,"tags":312},[199,40,161,313],"双指针",{"category":40,"tags":315},[199,40,161,178],{"category":40,"tags":317},[199,40,161,175],{"category":40,"tags":319},[199,40,161,320],"回溯",{"category":5,"tags":322},[323,324,325,326],"分布式处理与计算","Spark","Scala","RDD",{"category":5,"tags":328},[323,329,330,331],"线性回归","逻辑回归","监督学习",{"category":5,"tags":333},[323,334,335,336],"数值优化","牛顿法","收敛性",{"category":5,"tags":338},[323,339,340,341],"PCA","数据降维","正则化",{"category":5,"tags":343},[323,344,345,346],"聚类","层次聚类","K-Means",{"category":5,"tags":348},[323,349,350,351],"随机模拟","统计推断","EM算法",{"category":5,"tags":353},[24],{"category":5,"tags":355},[24],{"category":5,"tags":357},[24],{"category":40,"tags":359},[42,360],"图论",{"category":40,"tags":362},[42,363,364],"树","二叉树",{"category":40,"tags":366},[42,160],{"category":40,"tags":368},[42],{"category":40,"tags":370},[42,159],{"category":40,"tags":372},[42,40,373],"复杂度分析",{"category":40,"tags":375},[42,43,178],{"category":40,"tags":377},[42,43,188],{"category":40,"tags":379},[42,380],"基础概念",{"category":17,"tags":382},[383,384,385],"随记","照片","高中",{"category":17,"tags":387},[383,388,389],"团建","战地",{"category":17,"tags":391},[383,392],"生活",{"category":17,"tags":394},[383,395],"文学",{"category":17,"tags":397},[383,398,399],"SCP","模因",{"category":17,"tags":401},[383,402,403],"画集","艺术",{"category":17,"tags":405},[14,406,383],"写作",{"category":17,"tags":408},[383,409,410],"音乐","摇滚",{"category":17,"tags":412},[383,392],{"category":17,"tags":414},[383,409],{"category":17,"tags":416},[383,35,392],{"category":17,"tags":418},[383,419,420],"同人","手书",{"category":17,"tags":422},[383,392],{"category":17,"tags":424},[383,392],{"category":17,"tags":426},[383,427],"植物",{"category":17,"tags":429},[383,430],"读书",{"category":17,"tags":432},[383,392],{"category":17,"tags":434},[383,392],{"category":17,"tags":436},[383,392],{"category":17,"tags":438},[383,392],{"category":17,"tags":440},[383,392],{"category":17,"tags":442},[383,392],{"category":17,"tags":444},[14,445,383],"一周年",{"category":17,"tags":447},[383,392],{"category":17,"tags":449},[383,392],{"category":17,"tags":451},[35,452,453],"开源组织","SITE-193",{"category":17,"tags":455},[383,392],{"category":17,"tags":457},[383,458],"年末",{"category":17,"tags":460},[383,392],{"category":17,"tags":462},[383,392],{"category":17,"tags":464},[14,17],{"category":17,"tags":466},[383,392],{"category":17,"tags":468},[383,392],{"category":17,"tags":470},[383,392],{"category":17,"tags":472},[383,392],{"category":17,"tags":474},[383,475,476],"游戏","Control",{"category":30,"tags":478},[479,480,481,482],"Quadim","图像处理","四叉树","Rust",{"category":17,"tags":484},[14,485],"上线纪念",{"category":17,"tags":487},[383,395],{"category":30,"tags":489},[203,490],"测试",{"category":17,"tags":492},[383],{"category":17,"tags":494},[383,392],{"category":17,"tags":496},[383],{"category":5,"tags":498},[40],{"category":5,"tags":500},[40],{"category":5,"tags":502},[40],{"category":5,"tags":504},[40],{"category":5,"tags":506},[40],[508,512,516,520,524,528,532,536,540,544,548,552,556,560,564,568,572,576,579,583,587,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646,650,654,658,662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726,730,734,738,742,746,750,754,758,762,766,770,774,778,782,786,790,794,798,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865,869,873,877,881,885,889,893,897,901,904,907,911,915,919,923,927,930,934,938,942,946,950,954,957,961,965,969,973,977,981,984,988,992,996,1000,1004,1007,1011,1015,1019,1023,1027,1031,1035,1039,1043,1047,1051,1055,1059,1063,1067,1071,1075,1079],{"path":509,"words":510,"published":511,"date":156},"\u002Fposts\u002F2024\u002F2024-06-25-liteloaderqqnt",1296,"2024-06-25 11:03:08",{"path":513,"words":514,"published":515,"date":156},"\u002Fposts\u002F2024\u002F2024-06-26-ip签名",0,"2024-06-26 22:53:53",{"path":517,"words":518,"published":519,"date":156},"\u002Fposts\u002F2024\u002F2024-06-29-何加盐中文互联网正在加速崩塌",4853,"2024-06-29 00:47:13",{"path":521,"words":522,"published":523,"date":156},"\u002Fposts\u002F2024\u002F2024-07-12-github-chart",270,"2024-07-12 20:02:50",{"path":525,"words":526,"published":527,"date":156},"\u002Fposts\u002F2024\u002F2024-07-14-访客数统计",192,"2024-07-24 01:34:28",{"path":529,"words":530,"published":531,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-广大选课脚本",110,"2024-07-26 01:34:28",{"path":533,"words":534,"published":535,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数学分析笔记其二",14,"2024-07-26 23:54:02",{"path":537,"words":538,"published":539,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数据结构复习其二",12856,"2024-07-26 02:48:08",{"path":541,"words":542,"published":543,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数据结构复习相关",32856,"2024-07-26 02:24:14",{"path":545,"words":546,"published":547,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-线性代数与空间解析几何知识点全汇总",6110,"2024-07-26 03:27:55",{"path":549,"words":550,"published":551,"date":156},"\u002Fposts\u002F2024\u002F2024-07-31-typora-picgo-兰空图床打造markdown写作环境",311,"2024-07-31 12:56:23",{"path":553,"words":554,"published":555,"date":156},"\u002Fposts\u002F2024\u002F2024-09-02-jupyter配置中文",441,"2024-09-02 23:49:05",{"path":557,"words":558,"published":559,"date":156},"\u002Fposts\u002F2024\u002F2024-09-02-自定义vscode背景图片",100,"2024-09-02 23:39:00",{"path":561,"words":562,"published":563,"date":156},"\u002Fposts\u002F2024\u002F2024-09-03-制作gzhu校园网路由器",1423,"2024-09-03 23:43:18",{"path":565,"words":566,"published":567,"date":156},"\u002Fposts\u002F2024\u002F2024-09-26-09-25-2024",136,"2024-09-26 00:49:26",{"path":569,"words":570,"published":571,"date":156},"\u002Fposts\u002F2024\u002F2024-11-04-创建一个网络包解码器分析devp2p协议",1943,"2024-11-04 16:45:19",{"path":573,"words":574,"published":575,"date":156},"\u002Fposts\u002F2024\u002F2025-03-09-2024一些笔记常微分",16,"2024-12-09 22:51:00",{"path":577,"words":574,"published":578,"date":156},"\u002Fposts\u002F2024\u002F2025-03-09-2024一些笔记概率论","2025-03-09 22:51:00",{"path":580,"words":581,"published":582,"date":156},"\u002Fposts\u002F2025\u002F2025-03-01-windows下释放docker占用的wsl空间",164,"2025-03-01 13:54:15",{"path":584,"words":585,"published":586,"date":156},"\u002Fposts\u002F2025\u002F2025-03-01-爬虫实战-爬取广州大学课程表",774,"2025-03-01 14:55:48",{"path":588,"words":530,"published":589,"date":156},"\u002Fposts\u002F2025\u002F2025-04-03-hexo集成gitalk的问题","2025-04-03 14:26:34",{"path":591,"words":592,"published":593,"date":156},"\u002Fposts\u002F2025\u002F2025-09-22-记一次配置obsidian配合hexo写博客",92,"2025-09-22 16:47:52",{"path":595,"words":596,"published":597,"date":156},"\u002Fposts\u002F2025\u002F2025-10-24-10-20课题",204,"2025-10-24 08:15:01",{"path":599,"words":600,"published":601,"date":156},"\u002Fposts\u002F2025\u002F2025-11-02-组会朝花夕拾",501,"2025-11-02 18:56:59",{"path":603,"words":604,"published":605,"date":156},"\u002Fposts\u002F2025\u002F2025-11-05-基于随机加权推断模型im的参数估计算法",481,"2025-11-05 20:51:41",{"path":607,"words":608,"published":609,"date":156},"\u002Fposts\u002F2025\u002F2025-11-09-关于软考高项网规",884,"2025-11-09 19:54:52",{"path":611,"words":612,"published":613,"date":156},"\u002Fposts\u002F2025\u002F2025-11-17-arch-linux运行appimage相关",365,"2025-11-17 09:59:59",{"path":615,"words":616,"published":617,"date":156},"\u002Fposts\u002F2025\u002F2025-11-19-相关概念",2058,"2025-11-19 11:06:20",{"path":619,"words":620,"published":621,"date":156},"\u002Fposts\u002F2025\u002F2025-11-21-web可视化实践canvas",6393,"2025-11-21 14:50:48",{"path":623,"words":624,"published":625,"date":156},"\u002Fposts\u002F2025\u002F2025-11-22-使用-github-actions-自动部署基于vite的项目到-github-pages",272,"2025-11-23 01:59:24",{"path":627,"words":628,"published":629,"date":156},"\u002Fposts\u002F2025\u002F2025-11-22-关于前端包管理器npmpnpmyarn和bun",4890,"2025-11-22 21:21:15",{"path":631,"words":632,"published":633,"date":156},"\u002Fposts\u002F2025\u002F2025-11-23-undo-redo-机制具体实现",7839,"2025-11-23 19:15:00",{"path":635,"words":636,"published":637,"date":156},"\u002Fposts\u002F2025\u002F2025-11-27-前端安全-关于xss与crsf",1866,"2025-11-28 02:05:25",{"path":639,"words":640,"published":641,"date":156},"\u002Fposts\u002F2025\u002F2025-12-05-现代协同-2d-画布编辑器pixijs-v8",4285,"2025-12-05 02:00:16",{"path":643,"words":644,"published":645,"date":156},"\u002Fposts\u002F2025\u002F2025-12-07-杂谈-课题组系统设计",3710,"2025-12-07 21:09:33",{"path":647,"words":648,"published":649,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-javascript中的数组方法与栈stack和队列queue的实现",474,"2025-11-29 16:58:15",{"path":651,"words":652,"published":653,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于javascript-实现哈希表",189,"2025-11-27 11:31:39",{"path":655,"words":656,"published":657,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于javascript的set方法",332,"2025-12-25 15:26:18",{"path":659,"words":660,"published":661,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于动态规划(背包问题为例)",1238,"2025-11-17 18:24:04",{"path":663,"words":664,"published":665,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于滑动窗口",712,"2025-11-20 15:04:40",{"path":667,"words":668,"published":669,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于链表(javascript)",500,"2025-11-25 13:00:48",{"path":671,"words":672,"published":673,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-面试算法acm模式构建构建输入输出模板",2051,"2025-12-25 23:09:45",{"path":675,"words":676,"published":677,"date":156},"\u002Fposts\u002F2025\u002F2025-12-26-javascript-数字数组字符串的处理",483,"2025-12-26 11:20:25",{"path":679,"words":680,"published":681,"date":156},"\u002Fposts\u002F2025\u002F2025-12-26-javascripttypescript-的顺序表链表实现",446,"2025-12-26 12:16:12",{"path":683,"words":684,"published":685,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-前端画布设计vol-1-实现基础yuan素渲染和状态控制",2136,"2025-12-28 01:23:08",{"path":687,"words":688,"published":689,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-前端画布设计vol-2-实现富文本编辑",1838,"2025-12-28 02:58:47",{"path":691,"words":692,"published":693,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-算法刷题-关于链表操作",2135,"2025-12-27 16:12:42",{"path":695,"words":696,"published":697,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-配置dnscrypt-proxy实现加密dns服务windows",1899,"2025-11-15 01:06:37",{"path":699,"words":700,"published":701,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-关于网络请求xhrajaxfetchaxios",7788,"2025-10-28 15:48:46",{"path":703,"words":704,"published":705,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-接口封装与请求规范axios为例",2373,"2025-12-29 01:01:18",{"path":707,"words":708,"published":709,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-身份验证管理-基于-jwt-token-的实现",2709,"2025-11-23 22:04:41",{"path":711,"words":712,"published":713,"date":156},"\u002Fposts\u002F2025\u002F2025-12-29-记canvas画布项目开发",6254,"2025-12-29 04:52:15",{"path":715,"words":716,"published":717,"date":156},"\u002Fposts\u002F2025\u002Fabout-site",116,"2025-03-31 16:44:24",{"path":719,"words":720,"published":721,"date":156},"\u002Fposts\u002F2025\u002F使用neo4j图数据科学库gds进行中心度分析",143,"2025-04-02 23:37:24",{"path":723,"words":724,"published":725,"date":156},"\u002Fposts\u002F2026\u002F2026-01-03-论文实训草稿",10445,"2026-01-03 14:10:49",{"path":727,"words":728,"published":729,"date":156},"\u002Fposts\u002F2026\u002F2026-01-06-人工智能导论",11461,"2026-01-07 03:25:49",{"path":731,"words":732,"published":733,"date":156},"\u002Fposts\u002F2026\u002F2026-01-07-机器学习相关算法",82,"2026-01-08 02:28:13",{"path":735,"words":736,"published":737,"date":156},"\u002Fposts\u002F2026\u002F2026-01-16-关于低复杂度最长链共识算法设计",4466,"2026-01-16 10:33:23",{"path":739,"words":740,"published":741,"date":156},"\u002Fposts\u002F2026\u002F2026-01-19-杂记2026-01-19",5754,"2026-01-20 01:03:26",{"path":743,"words":744,"published":745,"date":156},"\u002Fposts\u002F2026\u002F2026-01-22-github-action-自动同步博客到-github-主页",1069,"2026-01-22 16:31:47",{"path":747,"words":748,"published":749,"date":156},"\u002Fposts\u002F2026\u002F2026-03-01-windows-wsl安装docker",257,"2026-03-01 20:55:31",{"path":751,"words":752,"published":753,"date":156},"\u002Fposts\u002F2026\u002F2026-03-14-关于-msys2",701,"2026-03-15 03:05:04",{"path":755,"words":756,"published":757,"date":156},"\u002Fposts\u002F2026\u002F2026-03-28-团队项目协作规范随记",2419,"2026-03-29 05:33:50",{"path":759,"words":760,"published":761,"date":156},"\u002Fposts\u002F2026\u002F2026-03-29-oh-my-posh配置分享",104,"2026-03-29 16:34:43",{"path":763,"words":764,"published":765,"date":156},"\u002Fposts\u002F2026\u002F2026-06-13-从上下文工程到-agent-harness-engineering",8840,"2026-06-13 21:06:20",{"path":767,"words":768,"published":769,"date":156},"\u002Fposts\u002F2026\u002F2026-07-13-简谈前端基建质量标准与ai友好建设",3814,"2026-07-13 21:06:20",{"path":771,"words":772,"published":773,"date":156},"\u002Fposts\u002F2026\u002F2026-07-15-agentic-rag-系统实践",13357,"2026-07-15 21:06:20",{"path":775,"words":776,"published":777,"date":156},"\u002Fposts\u002F2026\u002F2026-07-18-简谈sdd规范驱动开发-copy",4476,"2026-07-18 11:06:20",{"path":779,"words":780,"published":781,"date":156},"\u002Fposts\u002F2026\u002F2026-07-20-个人neovim配置分享",366,"2026-07-22 13:46:50",{"path":783,"words":784,"published":785,"date":156},"\u002Fposts\u002F2026\u002F2026-07-20-关于技术写作-设计文档",6763,"2026-07-20 13:46:50",{"path":787,"words":788,"published":789,"date":156},"\u002Fposts\u002F2026\u002F2026-07-29-fastapi-工程实践随记",3417,"2026-07-29 04:58:34",{"path":791,"words":792,"published":793,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-06-19-rfc-liskin_code_agent",3563,"2026-06-19 15:18:20",{"path":795,"words":796,"published":797,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-07-25-rfc-glushkov_ogas",13461,"2026-07-28 23:46:50",{"path":799,"words":800,"published":793,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-08-03-adr-ogas-arkhiv",2698,{"path":802,"words":803,"published":804,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002Frag\u002F2026-08-12-arkhiv_rag-vol-1",4366,"2026-08-12 15:18:20",{"path":806,"words":807,"published":808,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-25-力扣百题速练javascripttypescriptvol-1",3108,"2025-12-25 13:57:08",{"path":810,"words":811,"published":812,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-26-力扣百题速练javascripttypescriptvol-2",3185,"2025-12-26 13:57:08",{"path":814,"words":815,"published":816,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-28-力扣百题速练javascripttypescriptvol-3",2533,"2025-12-29 02:15:44",{"path":818,"words":819,"published":820,"date":156},"\u002Fposts\u002Fleetcode\u002F2026-01-17-力扣百题速练javascripttypescriptvol-4",3024,"2026-01-17 22:53:01",{"path":822,"words":823,"published":824,"date":156},"\u002Fposts\u002Fleetcode\u002F2026-01-19-力扣百题速练javascripttypescriptvol-5",293,"2026-01-19 15:15:12",{"path":826,"words":827,"published":828,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算spark系统与scala语言",4320,"2026-07-06 14:10:49",{"path":830,"words":831,"published":832,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算分类与回归分析",2081,"2026-07-07 12:40:29",{"path":834,"words":835,"published":836,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算数值优化方法",2182,"2026-07-07 13:50:29",{"path":838,"words":839,"published":840,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算数据降维",1583,"2026-07-07 21:50:29",{"path":842,"words":843,"published":844,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算聚类分析",1882,"2026-07-07 16:50:29",{"path":846,"words":847,"published":848,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算随机模拟与统计推断",2433,"2026-07-06 22:40:29",{"path":850,"words":851,"published":852,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-14-数据可视化-基本图像",10011,"2026-06-14 20:18:20",{"path":854,"words":855,"published":856,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-14-数据可视化-概论",10030,"2026-06-14 15:18:20",{"path":858,"words":859,"published":860,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-15-数据可视化-可视化库",2032,"2026-06-15 20:18:20",{"path":862,"words":863,"published":864,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-图",5451,"2025-04-15 20:48:06",{"path":866,"words":867,"published":868,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-树",4211,"2025-04-30 02:19:06",{"path":870,"words":871,"published":872,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-队列",921,"2025-04-11 15:30:08",{"path":874,"words":875,"published":876,"date":156},"\u002Fposts\u002F数据结构\u002F关于数据结构的一些想法",456,"2025-04-04 19:13:49",{"path":878,"words":879,"published":880,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-栈",920,"2025-04-18 00:17:37",{"path":882,"words":883,"published":884,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-算法复杂度",2153,"2025-04-05 16:09:55",{"path":886,"words":887,"published":888,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-线性表链表",4572,"2025-04-06 00:24:40",{"path":890,"words":891,"published":892,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-线性表顺序表",4191,"2025-04-05 22:09:59",{"path":894,"words":895,"published":896,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-绪论",2881,"2025-04-05 11:31:22",{"path":898,"words":899,"published":156,"date":900},"\u002Fposts\u002F杂记\u002F2023-12-26-2023年12月26日",7,"2023-12-26 23:51:33",{"path":902,"words":899,"published":156,"date":903},"\u002Fposts\u002F杂记\u002F2024-01-01-2024团建","2024-01-01 01:51:27",{"path":905,"words":581,"published":156,"date":906},"\u002Fposts\u002F杂记\u002F2024-01-09-随记","2024-01-09 20:50:35",{"path":908,"words":909,"published":156,"date":910},"\u002Fposts\u002F杂记\u002F2024-03-12-花名",5275,"2024-03-12 16:04:23",{"path":912,"words":913,"published":156,"date":914},"\u002Fposts\u002F杂记\u002F2024-04-15-逆模因",1353,"2024-04-15 00:26:16",{"path":916,"words":917,"published":156,"date":918},"\u002Fposts\u002F杂记\u002F2024-05-03-艺作",27,"2024-05-03 00:01:00",{"path":920,"words":921,"published":156,"date":922},"\u002Fposts\u002F杂记\u002F2024-05-21-关于博客",1720,"2024-02-21 23:21:11",{"path":924,"words":925,"published":156,"date":926},"\u002Fposts\u002F杂记\u002F2024-06-20-dnvrc维克多崔专访-2023",2036,"2024-06-20 00:28:39",{"path":928,"words":760,"published":156,"date":929},"\u002Fposts\u002F杂记\u002F2024-06-25-6月25日随记","2024-06-25 12:46:36",{"path":931,"words":932,"published":156,"date":933},"\u002Fposts\u002F杂记\u002F2024-06-25-歌名-想見星星",148,"2024-06-25 22:47:59",{"path":935,"words":936,"published":156,"date":937},"\u002Fposts\u002F杂记\u002F2024-07-11-桂花岗",6,"2024-07-11 00:28:17",{"path":939,"words":940,"published":156,"date":941},"\u002Fposts\u002F杂记\u002F2024-07-15-rolling-bocci",9,"2024-07-15 21:25:56",{"path":943,"words":944,"published":156,"date":945},"\u002Fposts\u002F杂记\u002F2024-07-22-七月九日",34,"2024-07-09 17:54:23",{"path":947,"words":948,"published":156,"date":949},"\u002Fposts\u002F杂记\u002F2024-07-22-六月随记",1052,"2024-07-22 01:03:19",{"path":951,"words":952,"published":156,"date":953},"\u002Fposts\u002F杂记\u002F2024-07-22-石菖蒲",41,"2024-07-10 01:26:05",{"path":955,"words":514,"published":156,"date":956},"\u002Fposts\u002F杂记\u002F2024-07-23-新书","2024-07-23 01:05:49",{"path":958,"words":959,"published":156,"date":960},"\u002Fposts\u002F杂记\u002F2024-07-29-年前",74,"2024-07-29 23:59:07",{"path":962,"words":963,"published":156,"date":964},"\u002Fposts\u002F杂记\u002F2024-07-30-周边",138,"2024-07-30 02:03:23",{"path":966,"words":967,"published":156,"date":968},"\u002Fposts\u002F杂记\u002F2024-07-31-2024-7-31日",185,"2024-07-31 01:21:52",{"path":970,"words":971,"published":156,"date":972},"\u002Fposts\u002F杂记\u002F2024-08-02-八月",1710,"2024-08-30 00:31:02",{"path":974,"words":975,"published":156,"date":976},"\u002Fposts\u002F杂记\u002F2024-09-01-九月",1484,"2024-09-26 16:30:15",{"path":978,"words":979,"published":156,"date":980},"\u002Fposts\u002F杂记\u002F2024-09-08-2024年9月8日",97,"2024-09-08 13:59:36",{"path":982,"words":514,"published":156,"date":983},"\u002Fposts\u002F杂记\u002F2024-09-19-博客站的一周年","2024-09-18 23:36:24",{"path":985,"words":986,"published":156,"date":987},"\u002Fposts\u002F杂记\u002F2024-10-03-十月",1028,"2024-10-31 23:54:27",{"path":989,"words":990,"published":156,"date":991},"\u002Fposts\u002F杂记\u002F2024-11-04-十一月",2134,"2024-11-30 00:04:39",{"path":993,"words":994,"published":156,"date":995},"\u002Fposts\u002F杂记\u002F2024-11-10-gzhu-site-193",80,"2024-11-10 19:19:12",{"path":997,"words":998,"published":156,"date":999},"\u002Fposts\u002F杂记\u002F2024-12-01-十二月",455,"2024-12-30 23:13:47",{"path":1001,"words":1002,"published":156,"date":1003},"\u002Fposts\u002F杂记\u002F2024-12-21-年末",23,"2024-12-21 23:21:49",{"path":1005,"words":522,"published":156,"date":1006},"\u002Fposts\u002F杂记\u002F2025-01-30-一月","2025-01-30 23:44:41",{"path":1008,"words":1009,"published":156,"date":1010},"\u002Fposts\u002F杂记\u002F2025-03-01-二月",224,"2025-02-28 00:11:08",{"path":1012,"words":1013,"published":156,"date":1014},"\u002Fposts\u002F杂记\u002F2025-03-01-博客杂谈",344,"2025-03-01 16:03:18",{"path":1016,"words":1017,"published":156,"date":1018},"\u002Fposts\u002F杂记\u002F2025-03-05-三月",2090,"2025-03-05 19:17:28",{"path":1020,"words":1021,"published":156,"date":1022},"\u002Fposts\u002F杂记\u002F2025-07-10-七月",361,"2025-07-10 22:04:32",{"path":1024,"words":1025,"published":156,"date":1026},"\u002Fposts\u002F杂记\u002F2025-09-21-九月",781,"2025-09-21 20:53:37",{"path":1028,"words":1029,"published":156,"date":1030},"\u002Fposts\u002F杂记\u002F2025-10-09-十月",591,"2025-10-09 00:35:07",{"path":1032,"words":1033,"published":156,"date":1034},"\u002Fposts\u002F杂记\u002Fcontrol",13,"2023-09-25 13:03:59",{"path":1036,"words":1037,"published":156,"date":1038},"\u002Fposts\u002F杂记\u002Fquadim四叉树图像处理",1094,"2023-10-21 11:27:06",{"path":1040,"words":1041,"published":156,"date":1042},"\u002Fposts\u002F杂记\u002Fsuccess",24,"2023-09-22 15:59:07",{"path":1044,"words":1045,"published":156,"date":1046},"\u002Fposts\u002F杂记\u002F三光年",295,"2023-11-18 04:18:40",{"path":1048,"words":1049,"published":156,"date":1050},"\u002Fposts\u002F杂记\u002F加密测试",961,"2023-11-21 14:24:01",{"path":1052,"words":1053,"published":156,"date":1054},"\u002Fposts\u002F杂记\u002F啊啊啊啊啊啊啊",54,"2023-09-20 17:29:33",{"path":1056,"words":1057,"published":156,"date":1058},"\u002Fposts\u002F杂记\u002F杂谈",124,"2023-09-25 23:11:32",{"path":1060,"words":1061,"published":156,"date":1062},"\u002Fposts\u002F杂记\u002F艹",25,"2023-10-21 17:40:43",{"path":1064,"words":1065,"published":1066,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习卷积神经网络",3168,"2026-06-07 11:23:08",{"path":1068,"words":1069,"published":1070,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习循环神经网络",2348,"2026-06-07 11:33:08",{"path":1072,"words":1073,"published":1074,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习改进学习方法",3360,"2026-06-07 10:13:08",{"path":1076,"words":1077,"published":1078,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习深度生成模型",2727,"2026-06-07 11:43:08",{"path":1080,"words":1081,"published":1082,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习神经网络基础",3205,"2026-06-07 10:03:08",{"id":1084,"title":1085,"abbrlink":1086,"body":1087,"category":40,"cover":156,"date":156,"description":1093,"extension":1899,"mathjax":1900,"meta":1901,"navigation":1900,"path":866,"published":868,"readingMinutes":534,"seo":1904,"stem":1905,"sticky":156,"swiper_index":156,"tags":1906,"updated":156,"words":867,"__hash__":1907},"posts\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-树.md","数据结构-树","19969",{"type":1088,"value":1089,"toc":1872},"minimark",[1090,1094,1099,1102,1109,1128,1131,1232,1243,1246,1292,1295,1298,1306,1309,1325,1328,1368,1372,1375,1381,1384,1390,1397,1403,1409,1415,1420,1430,1434,1437,1443,1446,1454,1458,1471,1474,1477,1483,1486,1514,1519,1525,1530,1535,1541,1544,1546,1551,1554,1560,1611,1614,1620,1623,1629,1632,1637,1643,1650,1653,1659,1664,1670,1673,1678,1681,1687,1690,1696,1699,1704,1707,1713,1716,1722,1727,1730,1735,1741,1744,1749,1752,1755,1761,1778,1781,1787,1792,1795,1798,1803,1814,1817,1823,1828,1831,1837,1843,1849,1852,1857,1860,1866,1869],[1091,1092,1093],"p",{},"树是常用的数据结构之一，种类很多比如二叉树，二叉查找树，平衡二叉树，红黑树，B 树，B+树等，本身就是一种递归结构",[1095,1096,1098],"h2",{"id":1097},"什么是树","什么是树？",[1091,1100,1101],{},"树是我们计算机中非常重要的一种数据结构，同时使用树这种数据结构，可以描述现实生活中的很多事物，例如家谱、单位的组织架构、等等。",[1091,1103,1104,1105,1108],{},"在计算机科学中，",[1106,1107,363],"strong",{},"是一种抽象数据类型（ADT）或是实现这种抽象数据类型的数据结构，用来模拟具有树状结构性质的数据集合。它是由 n（n>0）个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树，也就是说它是根朝上，而叶朝下的。它具有以下的特点：",[1110,1111,1112,1116,1119,1122,1125],"ul",{},[1113,1114,1115],"li",{},"每个节点都只有有限个子节点或无子节点；",[1113,1117,1118],{},"没有父节点的节点称为根节点；",[1113,1120,1121],{},"每一个非根节点有且只有一个父节点；",[1113,1123,1124],{},"除了根节点外，每个子节点可以分为多个不相交的子树；",[1113,1126,1127],{},"树里面没有环路(cycle)",[1095,1129,1130],{"id":1130},"术语",[1132,1133,1134,1140,1146,1156,1165,1174,1183,1189,1196,1202,1208,1214,1220,1226],"ol",{},[1113,1135,1136,1139],{},[1106,1137,1138],{},"节点的度","：一个节点含有的子树的个数称为该节点的度；",[1113,1141,1142,1145],{},[1106,1143,1144],{},"树的度","：一棵树中，最大的节点度称为树的度；",[1113,1147,1148,1151,1152,1155],{},[1106,1149,1150],{},"叶节点","或",[1106,1153,1154],{},"终端节点","：度为零的节点；",[1113,1157,1158,1151,1161,1164],{},[1106,1159,1160],{},"非终端节点",[1106,1162,1163],{},"分支节点","：度不为零的节点；",[1113,1166,1167,1151,1170,1173],{},[1106,1168,1169],{},"父亲节点",[1106,1171,1172],{},"父节点","：若一个节点含有子节点，则这个节点称为其子节点的父节点；",[1113,1175,1176,1151,1179,1182],{},[1106,1177,1178],{},"孩子节点",[1106,1180,1181],{},"子节点","：一个节点含有的子树的根节点称为该节点的子节点；",[1113,1184,1185,1188],{},[1106,1186,1187],{},"兄弟节点","：具有相同父节点的节点互称为兄弟节点；",[1113,1190,1191,1192,1195],{},"节点的",[1106,1193,1194],{},"层次","：从根开始定义起，根为第 1 层，根的子节点为第 2 层，以此类推；",[1113,1197,1198,1201],{},[1106,1199,1200],{},"深度","：对于任意节点 n,n 的深度为从根到 n 的唯一路径长，根的深度为 0；",[1113,1203,1204,1207],{},[1106,1205,1206],{},"高度","：对于任意节点 n,n 的高度为从 n 到一片树叶的最长路径长，所有树叶的高度为 0；",[1113,1209,1210,1213],{},[1106,1211,1212],{},"堂兄弟节点","：父节点在同一层的节点互为堂兄弟；",[1113,1215,1216,1219],{},[1106,1217,1218],{},"节点的祖先","：从根到该节点所经分支上的所有节点；",[1113,1221,1222,1225],{},[1106,1223,1224],{},"子孙","：以某节点为根的子树中任一节点都称为该节点的子孙。",[1113,1227,1228,1231],{},[1106,1229,1230],{},"森林","：由 m（m>=0）棵互不相交的树的集合称为森林；",[1233,1234,1240],"pre",{"className":1235,"code":1237,"language":1238,"meta":1239},[1236],"language-less","                    A (根节点)\n                   \u002F \\\n                  B   C\n                 \u002F \\   \\\n                D   E   F\n               \u002F       \u002F \\\n              G       H   I (叶节点)\n             \u002F \\\n            J   K (叶节点)\n\n\n- A是根节点，没有父节点\n- B是A的子节点，A是B的父节点\n- B和C是兄弟节点（具有相同父节点A）\n- G是叶节点（度为0）\n- B是非终端节点（度不为0，度为2）\n- 从A到K的路径长度为3，K的深度为3\n- 树的度为2（B节点的度最大）\n- B的度为2（有两个子节点D和E）\n- 整个结构是一个有序树（子节点有左右顺序）\n","less","",[1241,1242,1237],"code",{"__ignoreMap":1239},[1091,1244,1245],{},"这个图示展示了以下树的基本概念：",[1132,1247,1248,1254,1260,1265,1270,1276,1281,1286],{},[1113,1249,1250,1253],{},[1106,1251,1252],{},"根节点","：A 节点，整棵树的起始点",[1113,1255,1256,1259],{},[1106,1257,1258],{},"父节点与子节点关系","：如 A 是 B 和 C 的父节点，B 和 C 是 A 的子节点",[1113,1261,1262,1264],{},[1106,1263,1187],{},"：B 和 C 具有相同的父节点 A，所以它们是兄弟节点",[1113,1266,1267,1269],{},[1106,1268,1150],{},"：G、H、I、J、K 这些没有子节点的节点",[1113,1271,1272,1275],{},[1106,1273,1274],{},"内部节点","：A、B、C、D、E、F 这些有子节点的节点",[1113,1277,1278,1280],{},[1106,1279,1138],{},"：B 的度为 2（有两个子节点），G 的度为 2（有两个子节点）",[1113,1282,1283,1285],{},[1106,1284,1144],{},"：整棵树的最大节点度，这里是 2",[1113,1287,1288,1291],{},[1106,1289,1290],{},"路径与深度","：从根节点 A 到任意节点的路径，如 A->B->D->G 的路径长度为 3",[1095,1293,1294],{"id":1294},"树的种类",[1091,1296,1297],{},"有序\u002F无序：",[1110,1299,1300,1303],{},[1113,1301,1302],{},"无序树：树中任意节点的子节点之间没有顺序关系，这种树称为无序树，也称为自由树。",[1113,1304,1305],{},"有序树\u002F搜索树\u002F查找树：树中任意节点的子节点之间有顺序关系，这种树称为有序树。即树的所有节点按照一定的顺序排列，这样进行插入、删除、查找时效率就会非常高",[1091,1307,1308],{},"平衡\u002F不平衡：",[1110,1310,1311,1322],{},[1113,1312,1313,1314],{},"平衡树\n",[1110,1315,1316,1319],{},[1113,1317,1318],{},"绝对平衡树：所有叶节点在同一层",[1113,1320,1321],{},"非绝对平衡树",[1113,1323,1324],{},"不平衡树",[1091,1326,1327],{},"节点的分叉情况：",[1110,1329,1330,1360],{},[1113,1331,1332,1333],{},"等叉树：是每个节点的键值个数都相同、子节点个数也都相同\n",[1110,1334,1335,1354,1357],{},[1113,1336,1337,1338],{},"二叉树：每个节点最多含有两个子树的树称为二叉树；\n",[1110,1339,1340,1348,1351],{},[1113,1341,1342,1343],{},"完全二叉树：除了第 d 层外，其它各层的节点数目均已达最大值，且第 d 层所有节点从左向右连续地紧密排列，这样的二叉树被称为完全二叉树；\n",[1110,1344,1345],{},[1113,1346,1347],{},"满二叉树：所有叶节点都在最底层的完全二叉树；",[1113,1349,1350],{},"平衡二叉树、AVL 树：当且仅当任何节点的两棵子树的高度差不大于 1 的二叉树；",[1113,1352,1353],{},"排序二叉树：也称二叉查找树、二叉搜索树、有序二叉树；",[1113,1355,1356],{},"霍夫曼树：带权路径最短的二叉树称为哈夫曼树或最优二叉树；",[1113,1358,1359],{},"多叉树",[1113,1361,1362,1363],{},"不等叉树：每个节点的键值个数不一定相同、子节点个数也不一定相同\n",[1110,1364,1365],{},[1113,1366,1367],{},"B 树：对不等叉树的节点键值数和插入、删除逻辑添加一些特殊的要求，使其能达到绝对平衡的效果。B 树全称 Balance Tree。如果某个 B 树上所有节点的分叉数最大值是 m，则把这个 B 数叫做 m 阶 B 树。",[1095,1369,1370],{"id":364},[1106,1371,364],{},[1091,1373,1374],{},"二叉树就像它的名字一样，每个元素最多有两个节点，分别称为左节点和右节点。当然并不是每个元素都需要有两个节点，有的可能只有左节点，有的可能只有右节点。",[1233,1376,1379],{"className":1377,"code":1378,"language":1238,"meta":1239},[1236],"                    A (根节点)\n                   \u002F \\\n                  B   C\n                 \u002F \\   \\\n                D   E   F\n               \u002F       \u002F \\\n              G       H   I (叶节点)\n             \u002F \\\n            J   K (叶节点)\n",[1241,1380,1378],{"__ignoreMap":1239},[1091,1382,1383],{},"基于树的存储模式的不同，为了更好的利用存储空间，二叉树又分为完全二叉树和非完全二叉树：",[1091,1385,1386,1389],{},[1106,1387,1388],{},"「完全二叉树」","：叶子节点都在最底下两层，最后一层的叶子节点都靠左排列，并且除了最后一层，其他层的节点个数都要达到最大",[1391,1392,1394],"h3",{"id":1393},"１完全二叉树",[1106,1395,1396],{},"１、完全二叉树",[1233,1398,1401],{"className":1399,"code":1400,"language":1238,"meta":1239},[1236],"                    A (根节点)\n                   \u002F \\\n                  B   C\n                 \u002F \\   \\\n                D   E   F\n               \u002F       \u002F \\\n              G       H   I (叶节点)\n             \u002F \\\n            J   K (叶节点)\n\n完全二叉树的顺序存储\n数组索引: [0][1][2][3][4][5][6][7][8]\n存储内容: [1][2][3][4][5][6][7][8][9]\n",[1241,1402,1400],{"__ignoreMap":1239},[1391,1404,1406],{"id":1405},"２非完全二叉树",[1106,1407,1408],{},"２、非完全二叉树",[1233,1410,1413],{"className":1411,"code":1412,"language":1238,"meta":1239},[1236],"        1\n       \u002F \\\n      2   3\n     \u002F     \\\n    4       5\n   \u002F       \u002F \\\n  6       7   8\n         \u002F\n        9\n\n非完全二叉树的顺序存储\n数组索引: [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18]\n存储内容: [1][2][3][4][ ][ ][5][6][ ][ ][ ][ ][ ][7][8][ ][ ][ ][9]\n存在大量空位，造成空间浪费\n\n",[1241,1414,1412],{"__ignoreMap":1239},[1095,1416,1418],{"id":1417},"二叉树的存储模式",[1106,1419,1417],{},[1091,1421,1422,1423,1426,1427],{},"二叉树的存储模式有两种，一种是基于指针或者引用的",[1106,1424,1425],{},"二叉链式存储法","，一种是基于数组的",[1106,1428,1429],{},"顺序存储法",[1391,1431,1432],{"id":1425},[1106,1433,1425],{},[1091,1435,1436],{},"链式存储法相对比较简单，理解起来也非常容易，每一个节点都有三个字段，一个字段存储着该节点的值，另外两个字段存储着左右节点的引用。我们顺着跟字节就可以很轻松的把整棵树串起来",[1233,1438,1441],{"className":1439,"code":1440,"language":1238,"meta":1239},[1236],"链式存储法结构示意图：\n\n    节点A\n   \u002F     \\\n  ↓       ↓\n节点B    节点C\n\u002F   \\     \u002F   \\\n↓    ↓   ↓    ↓\n...  ... ...  ...\n\n每个节点的内存结构：\n┌─────────────┬─────────────┬─────────────┐\n│    data     │    left     │    right    │\n│  (节点值)   │  (左子节点) │  (右子节点) │\n└─────────────┴─────────────┴─────────────┘\n      ↓              ↓             ↓\n    节点值       指向左子树    指向右子树\n                   的指针        的指针\n\n",[1241,1442,1440],{"__ignoreMap":1239},[1091,1444,1445],{},"链式存储法的 C 语言实现：",[1233,1447,1452],{"className":1448,"code":1450,"language":1451,"meta":1239},[1449],"language-c","#include \u003Cstdio.h>\n#include \u003Cstdlib.h>\n\n\u002F\u002F 二叉树节点定义\ntypedef struct TreeNode {\n    int data;           \u002F\u002F 节点数据\n    struct TreeNode* left;   \u002F\u002F 左子节点指针\n    struct TreeNode* right;  \u002F\u002F 右子节点指针\n} TreeNode;\n\n\u002F\u002F 创建新节点\nTreeNode* createNode(int data) {\n    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));\n    newNode->data = data;\n    newNode->left = NULL;\n    newNode->right = NULL;\n    return newNode;\n}\n\n\u002F\u002F 示例：构建一个简单的二叉树\nTreeNode* buildSampleTree() {\n    TreeNode* root = createNode(1);\n    root->left = createNode(2);\n    root->right = createNode(3);\n    root->left->left = createNode(4);\n    root->left->right = createNode(5);\n    return root;\n}\n\n\u002F\u002F 释放链式存储的二叉树内存\nvoid freeTree(TreeNode* root) {\n    if (root == NULL) {\n        return;\n    }\n    freeTree(root->left);\n    freeTree(root->right);\n    free(root);\n}\n\n\u002F\u002F 使用示例\nvoid demonstrateStorageMethods() {\n    printf(\"=== 二叉树两种存储方式演示 ===\\n\");\n\n    \u002F\u002F 1. 链式存储法\n    printf(\"\\n1. 链式存储法:\\n\");\n    TreeNode* linkedTree = buildSampleTree();\n    printf(\"前序遍历结果: \");\n    preOrderLinked(linkedTree);\n    printf(\"\\n\");\n    freeTree(linkedTree);\n\n    \u002F\u002F 2. 顺序存储法\n    printf(\"\\n2. 顺序存储法:\\n\");\n    buildCompleteBinaryTree();\n    printArrayTree();\n    printf(\"前序遍历结果: \");\n    preOrderArray(0);\n    printf(\"\\n\");\n}\n\n\u002F*\n对比两种存储方式：\n\n1. 链式存储法：\n   - 优点：灵活，不需要大片连续内存，插入删除节点方便\n   - 缺点：需要额外空间存储指针，遍历时需要多次内存跳转\n\n2. 顺序存储法：\n   - 优点：节省指针空间，访问节点速度快（通过数组下标直接访问）\n   - 缺点：对于非完全二叉树会造成空间浪费，插入删除节点复杂\n*\u002F\n\nint main() {\n    demonstrateStorageMethods();\n    return 0;\n}\n","c",[1241,1453,1450],{"__ignoreMap":1239},[1391,1455,1456],{"id":1429},[1106,1457,1429],{},[1091,1459,1460,1461,1464,1465,1467,1468,1470],{},"顺序存储法是基于数组实现的，数组是一段有序的内存空间，如果我们把跟节点的坐标定位",[1241,1462,1463],{},"i","=1，左节点就是 2 * ",[1241,1466,1463],{}," = 2，右节点 2 * ",[1241,1469,1463],{},"+ 1 = 3，以此类推，每个节点都这么算，然后就将树转化成数组了，反过来，按照这种规则我们也能将数组转化成一棵树。",[1091,1472,1473],{},"于是在这里我们就能发现一个问题：如果这是一颗不平衡的二叉树是不是会造成大量的空间浪费？这就是为什么需要分完全二叉树和非完全二叉树，分别来看看这两种树基于数组的存储模式。",[1091,1475,1476],{},"顺序存储法的 C 语言实现：",[1233,1478,1481],{"className":1479,"code":1480,"language":1451,"meta":1239},[1449],"#include \u003Cstdio.h>\n#include \u003Cstdlib.h>\n#define MAX_TREE_SIZE 100\n\n\u002F\u002F 用数组表示二叉树\nint treeArray[MAX_TREE_SIZE];\nint treeSize = 0;\n\n\u002F\u002F 初始化数组\nvoid initTreeArray() {\n    for (int i = 0; i \u003C MAX_TREE_SIZE; i++) {\n        treeArray[i] = -1; \u002F\u002F -1表示空节点\n    }\n}\n\n\u002F\u002F 在指定位置插入节点\nvoid insertNode(int index, int data) {\n    if (index >= MAX_TREE_SIZE) {\n        printf(\"数组越界\\n\");\n        return;\n    }\n    treeArray[index] = data;\n    if (index >= treeSize) {\n        treeSize = index + 1;\n    }\n}\n\n\u002F\u002F 获取父节点索引\nint getParentIndex(int index) {\n    if (index \u003C= 0) return -1;\n    return (index - 1) \u002F 2;\n}\n\n\u002F\u002F 获取左子节点索引\nint getLeftChildIndex(int index) {\n    int leftIndex = 2 * index + 1;\n    return (leftIndex \u003C MAX_TREE_SIZE) ? leftIndex : -1;\n}\n\n\u002F\u002F 获取右子节点索引\nint getRightChildIndex(int index) {\n    int rightIndex = 2 * index + 2;\n    return (rightIndex \u003C MAX_TREE_SIZE) ? rightIndex : -1;\n}\n\n\u002F\u002F 示例：构建完全二叉树\nvoid buildCompleteBinaryTree() {\n    initTreeArray();\n    \u002F\u002F 构建一个简单的完全二叉树: 1, 2, 3, 4, 5\n    \u002F\u002F       1\n    \u002F\u002F      \u002F \\\n    \u002F\u002F     2   3\n    \u002F\u002F    \u002F \\\n    \u002F\u002F   4   5\n    insertNode(0, 1);  \u002F\u002F 根节点\n    insertNode(1, 2);  \u002F\u002F 1的左子节点\n    insertNode(2, 3);  \u002F\u002F 1的右子节点\n    insertNode(3, 4);  \u002F\u002F 2的左子节点\n    insertNode(4, 5);  \u002F\u002F 2的右子节点\n}\n\n\u002F\u002F 打印数组表示的二叉树（层序遍历）\nvoid printArrayTree() {\n    printf(\"数组存储的二叉树: \");\n    for (int i = 0; i \u003C treeSize; i++) {\n        if (treeArray[i] != -1) {\n            printf(\"%d \", treeArray[i]);\n        } else {\n            printf(\"NULL \");\n        }\n    }\n    printf(\"\\n\");\n}\n\n\u002F\u002F 前序遍历（数组实现）\nvoid preOrderArray(int index) {\n    if (index >= treeSize || treeArray[index] == -1) {\n        return;\n    }\n    printf(\"%d \", treeArray[index]);\n    preOrderArray(2 * index + 1);  \u002F\u002F 左子树\n    preOrderArray(2 * index + 2);  \u002F\u002F 右子树\n}\n\n\u002F\u002F 前序遍历（链式存储）\nvoid preOrderLinked(TreeNode* root) {\n    if (root == NULL) {\n        return;\n    }\n    printf(\"%d \", root->data);\n    preOrderLinked(root->left);\n    preOrderLinked(root->right);\n}\n\n",[1241,1482,1480],{"__ignoreMap":1239},[1091,1484,1485],{},"对比两种存储方式：",[1132,1487,1488,1502],{},[1113,1489,1490,1493,1494],{},[1106,1491,1492],{},"链式存储法","：",[1110,1495,1496,1499],{},[1113,1497,1498],{},"优点：灵活，不需要大片连续内存，插入删除节点方便",[1113,1500,1501],{},"缺点：需要额外空间存储指针，遍历时需要多次内存跳转",[1113,1503,1504,1493,1506],{},[1106,1505,1429],{},[1110,1507,1508,1511],{},[1113,1509,1510],{},"优点：节省指针空间，访问节点速度快（通过数组下标直接访问）",[1113,1512,1513],{},"缺点：对于非完全二叉树会造成空间浪费，插入删除节点复杂",[1391,1515,1517],{"id":1516},"完全二叉树顺序存储法",[1106,1518,1516],{},[1233,1520,1523],{"className":1521,"code":1522,"language":1238,"meta":1239},[1236],"完全二叉树结构：\n        1\n       \u002F \\\n      2   3\n     \u002F \\ \u002F \\\n    4  5 6  7\n   \u002F\n  8\n\n数组存储方式（索引从0开始）：\n索引:  [0][1][2][3][4][5][6][7]\n值:    [1][2][3][4][5][6][7][8]\n\n父子节点关系：\n- 父节点索引为 i，则左子节点索引为 2*i+1，右子节点索引为 2*i+2\n- 子节点索引为 j，则父节点索引为 (j-1)\u002F2（整数除法）\n\n具体对应关系：\n- 节点1(索引0): 左子节点2(索引1), 右子节点3(索引2)\n- 节点2(索引1): 左子节点4(索引3), 右子节点5(索引4)\n- 节点3(索引2): 左子节点6(索引5), 右子节点7(索引6)\n- 节点4(索引3): 左子节点8(索引7), 无右子节点\n- 节点5-8(索引4-7): 均为叶节点，无子节点\n",[1241,1524,1522],{"__ignoreMap":1239},[1391,1526,1528],{"id":1527},"非完全二叉树顺序存储法",[1106,1529,1527],{},[1233,1531,1533],{"className":1532,"code":1522,"language":1238,"meta":1239},[1236],[1241,1534,1522],{"__ignoreMap":1239},[1091,1536,1537,1538],{},"从图中将树转化成数组之后可以看出，完全二叉树用数组来存储只浪费了一个下标为 0 的存储空间，非完全二叉树则浪费了大量的空间。\n",[1106,1539,1540],{},"「如果树为完全二叉树，用数组存储比链式存储节约空间，因为数组存储不需要存储左右节点的信息」",[1542,1543],"hr",{},[1542,1545],{},[1095,1547,1549],{"id":1548},"二叉树遍历",[1106,1550,1548],{},[1091,1552,1553],{},"要了解二叉树的遍历，我们首先需要实例化出一颗二叉树，我们采用链式存储的方式来定义树，实例化树需要树的节点信息，用来存放该节点的信息，因为我们才用的是链式存储，所以我们的节点信息如下。",[1233,1555,1558],{"className":1556,"code":1557,"language":1451,"meta":1239},[1449],"\u002F**\n * 定义一棵树\n *\u002F\n\u002F* 树节点的定义 *\u002F\n#define MAX_TREE_SIZE 100\n\ntypedef struct\n{\n  TElemType data;\n  int parent; \u002F* 父节点位置域 *\u002F\n} PTNode;\n\ntypedef struct\n{\n  PTNode nodes[MAX_TREE_SIZE];\n  int n; \u002F* 节点数 *\u002F\n} PTree;\n\n\u002F* 二叉树节点的定义 *\u002F\ntypedef struct TreeNode {\n    int data;\n    struct TreeNode* left;\n    struct TreeNode* right;\n} TreeNode;\n",[1241,1559,1557],{"__ignoreMap":1239},[1132,1561,1562,1587],{},[1113,1563,1564,1565,1568,1569],{},"使用  ",[1241,1566,1567],{},"PTNode","  结构体表示树的节点，包含：\n",[1110,1570,1571,1581],{},[1113,1572,1573,1576,1577,1580],{},[1241,1574,1575],{},"data","：存储节点数据（类型为  ",[1241,1578,1579],{},"TElemType","）",[1113,1582,1583,1586],{},[1241,1584,1585],{},"parent","：存储父节点在数组中的索引位置",[1113,1588,1564,1589,1592,1593],{},[1241,1590,1591],{},"PTree","  结构体表示整棵树，包含：\n",[1110,1594,1595,1605],{},[1113,1596,1597,1600,1601,1604],{},[1241,1598,1599],{},"nodes","：节点数组，最多可容纳  ",[1241,1602,1603],{},"MAX_TREE_SIZE","  个节点",[1113,1606,1607,1610],{},[1241,1608,1609],{},"n","：实际节点数量",[1091,1612,1613],{},"定义完节点信息之后，我们就可以初始化一颗树啦，下面是初始化树的过程:",[1233,1615,1618],{"className":1616,"code":1617,"language":1451,"meta":1239},[1449],"TreeNode* buildTree() {\n\u002F\u002F 创建测试用的二叉树\nTreeNode* t1 = (TreeNode*)malloc(sizeof(TreeNode));\nTreeNode* t2 = (TreeNode*)malloc(sizeof(TreeNode));\nTreeNode* t3 = (TreeNode*)malloc(sizeof(TreeNode));\nTreeNode* t4 = (TreeNode*)malloc(sizeof(TreeNode));\nTreeNode* t5 = (TreeNode*)malloc(sizeof(TreeNode));\nTreeNode* t6 = (TreeNode*)malloc(sizeof(TreeNode));\nTreeNode* t7 = (TreeNode*)malloc(sizeof(TreeNode));\nTreeNode* t8 = (TreeNode\\*)malloc(sizeof(TreeNode));\n\n    t1->data = 1;\n    t2->data = 2;\n    t3->data = 3;\n    t4->data = 4;\n    t5->data = 5;\n    t6->data = 6;\n    t7->data = 7;\n    t8->data = 8;\n\n    t1->left = t2;\n    t1->right = t3;\n    t2->left = t4;\n    t4->right = t7;\n    t3->left = t5;\n    t3->right = t6;\n    t6->left = t8;\n\n    t2->right = NULL;\n    t3->left = t5;\n    t3->right = t6;\n    t4->left = NULL;\n    t4->right = t7;\n    t5->left = NULL;\n    t5->right = NULL;\n    t6->left = t8;\n    t6->right = NULL;\n    t7->left = NULL;\n    t7->right = NULL;\n    t8->left = NULL;\n    t8->right = NULL;\n\n    return t1;\n\n}\n\n",[1241,1619,1617],{"__ignoreMap":1239},[1091,1621,1622],{},"经过上面步骤之后，我们的树就长成下图所示的样子，数字代表该节点的值。",[1233,1624,1627],{"className":1625,"code":1626,"language":1238,"meta":1239},[1236],"构建的二叉树结构：\n\n        1\n       \u002F \\\n      2   3\n     \u002F   \u002F \\\n    4   5   6\n     \\     \u002F\n      7   8\n\nt1->left = t2; \u002F\u002F 节点1的左子节点是节点2\nt1->right = t3; \u002F\u002F 节点1的右子节点是节点3\nt2->left = t4; \u002F\u002F 节点2的左子节点是节点4\nt4->right = t7; \u002F\u002F 节点4的右子节点是节点7\nt3->left = t5; \u002F\u002F 节点3的左子节点是节点5\nt3->right = t6; \u002F\u002F 节点3的右子节点是节点6\nt6->left = t8; \u002F\u002F 节点6的左子节点是节点8\n\n节点连接关系：\n- 节点1是根节点，左子节点为2，右子节点为3\n- 节点2的左子节点为4，右子节点为NULL\n- 节点3的左子节点为5，右子节点为6\n- 节点4的左子节点为NULL，右子节点为7\n- 节点5的左子节点为NULL，右子节点为NULL\n- 节点6的左子节点为8，右子节点为NULL\n- 节点7和8都是叶节点，没有子节点\n",[1241,1628,1626],{"__ignoreMap":1239},[1091,1630,1631],{},"有了树之后，我们就可以对树进行遍历\n二叉树的遍历有三种方式，前序遍历，中序遍历，后续遍历三种遍历方式，三种遍历方式与节点输出的顺序有关系",[1391,1633,1635],{"id":1634},"前序遍历",[1106,1636,1634],{},[1091,1638,1639,1642],{},[1106,1640,1641],{},"「前序遍历」","：对于树中的任意节点来说，先打印这个节点，然后再打印它的左子树，最后打印它的右子树。",[1091,1644,1645],{},[1646,1647],"img",{"alt":1648,"src":1649},"动图封面","https:\u002F\u002Fpic1.zhimg.com\u002Fv2-8c5bca63a9ce3aa30a46e37942281684_b.webp",[1091,1651,1652],{},"理解了前序遍历的概念和看完前序遍历执行流程动态图之后，你心里一定很想知道，在代码中如何怎么实现树的前序遍历？二叉树的遍历非常简单，一般都是采用递归的方式进行遍历，我们来看看前序遍历的代码：",[1233,1654,1657],{"className":1655,"code":1656,"language":1451,"meta":1239},[1449],"\n\u002F\u002F 先序遍历，递归实现 先打印本身，再打印左节点，在打印右节点\nvoid preOrder(TreeNode\\* root) {\nif (root == NULL) {\nreturn;\n}\n\u002F\u002F 输出本身\nprintf(\"%d \", root->data);\n\u002F\u002F 遍历左节点\npreOrder(root->left);\n\u002F\u002F 遍历右节点\npreOrder(root->right);\n}\n\n",[1241,1658,1656],{"__ignoreMap":1239},[1391,1660,1662],{"id":1661},"中序遍历",[1106,1663,1661],{},[1091,1665,1666,1669],{},[1106,1667,1668],{},"「中序遍历」","：对于树中的任意节点来说，先打印它的左子树，然后再打印它本身，最后打印它的右子树。",[1091,1671,1672],{},"跟前序遍历一样，我们来看看中序遍历的执行流程动态图。",[1091,1674,1675],{},[1646,1676],{"alt":1648,"src":1677},"https:\u002F\u002Fpic3.zhimg.com\u002Fv2-46511b7421ee1ce8534fcbd580d9a316_b.webp",[1091,1679,1680],{},"中序遍历的代码：",[1233,1682,1685],{"className":1683,"code":1684,"language":1451,"meta":1239},[1449],"\n\u002F\u002F 中序遍历 先打印左节点，再输出本身，最后输出右节点\nvoid inOrder(TreeNode\\* root) {\nif (root == NULL) {\nreturn;\n}\ninOrder(root->left);\nprintf(\"%d \", root->data);\ninOrder(root->right);\n}\n\n",[1241,1686,1684],{"__ignoreMap":1239},[1391,1688,1689],{"id":1689},"后序遍历",[1091,1691,1692,1695],{},[1106,1693,1694],{},"「后序遍历」","：对于树中的任意节点来说，先打印它的左子树，然后再打印它的右子树，最后打印这个节点本身。",[1091,1697,1698],{},"跟前两种遍历一样，理解概念之后，我们还是先来看张图。",[1091,1700,1701],{},[1646,1702],{"alt":1648,"src":1703},"https:\u002F\u002Fpic2.zhimg.com\u002Fv2-99b3066d8e4f5d268302acea5e20568f_b.webp",[1091,1705,1706],{},"后序遍历的实现代码：",[1233,1708,1711],{"className":1709,"code":1710,"language":1451,"meta":1239},[1449],"\n\u002F\u002F 后序遍历 先打印左节点，再输出右节点，最后才输出本身\nvoid postOrder(TreeNode\\* root) {\nif (root == NULL) {\nreturn;\n}\npostOrder(root->left);\npostOrder(root->right);\nprintf(\"%d \", root->data);\n}\n\n",[1241,1712,1710],{"__ignoreMap":1239},[1091,1714,1715],{},"二叉树有三种遍历方式，但都是一样的，只是输出的顺序不一样",[1091,1717,1718,1719],{},"接下来还有一种常用而且比较特殊的二叉树：",[1106,1720,1721],{},"「二叉查找树」",[1095,1723,1725],{"id":1724},"二叉查找树",[1106,1726,1724],{},[1091,1728,1729],{},"二叉查找树又叫二叉搜索树，从名字中我们就能够知道，这种树在查找方面一定有过人的优势，事实确实如此，二叉查找树确实是为查找而生的树，但是它不仅仅支持快速查找数据，还支持快速插入、删除一个数据",[1091,1731,1732,1734],{},[1106,1733,1721],{},"：在树中的任意一个节点，其左子树中的每个节点的值，都要小于这个节点的值，而右子树节点的值都大于这个节点的值，下面定义了一颗二叉查找树",[1233,1736,1739],{"className":1737,"code":1738,"language":1238,"meta":1239},[1236],"        62\n       \u002F  \\\n      58   88\n     \u002F  \\ \u002F  \\\n    47  51 73  99\n   \u002F           \u002F\n  35          93\n   \\\n    37\n   \u002F  \\\n  36  39\n       \\\n        42\n\n- 对于任意节点，其左子树中的所有节点值都小于该节点值\n- 其右子树中的所有节点值都大于该节点值\n- 根节点 `62`：左子树所有节点（58, 47, 35, 37, 36, 39, 42, 51）都小于 62；右子树所有节点（88, 73, 99, 93）都大于 62\n- 节点 `58`：左子树（47, 35, 37, 36, 39, 42）都小于 58；右子树（51）大于 58\n- 节点 `88`：左子树（73）小于 88；右子树（99, 93）大于 88\n",[1241,1740,1738],{"__ignoreMap":1239},[1091,1742,1743],{},"根据二叉查找树的定义，每棵树的左节点的值要小于这父节点，右节点的值要大于父节点\n下面从二叉查找树的查找开始学习二叉查找树",[1095,1745,1747],{"id":1746},"二叉查找树的查找操作",[1106,1748,1746],{},[1091,1750,1751],{},"由于二叉查找树的特性，我们需要查找一个数据，先跟跟节点比较，如果值等于跟节点，则返回根节点，如果小于根节点，则必然在左子树这边，只要递归查找左子树就行，如果大于，这在右子树这边，递归右子树即可。这样就能够实现快速查找，因为每次查找都减少了一半的数据，跟二分查找有点相似，快速插入、删除都是居于这个特性实现的。",[1091,1753,1754],{},"下面用一幅动态图来加强对二叉查找树查找流程的理解，在上面的这颗二叉查找树中找出值等于 37 的节点：",[1091,1756,1757],{},[1646,1758],{"alt":1759,"src":1760},"动图","https:\u002F\u002Fpic1.zhimg.com\u002Fv2-dbca7edcda530ecf983b42216772dfae_b.webp",[1110,1762,1763,1766,1769,1772,1775],{},[1113,1764,1765],{},"1、先用 37 跟 62 比较，37 \u003C 62 ，在左子树中继续查找",[1113,1767,1768],{},"２、左子树的节点值为 58，37 \u003C 58 ，继续在左子树中查找",[1113,1770,1771],{},"３、左子树的节点值为 47，37 \u003C 47，继续在左子树中查找",[1113,1773,1774],{},"４、左子树的节点值为 35，37 > 35，在右子树中查找",[1113,1776,1777],{},"５、右子树中的节点值为 37，37 = 37 ，返回该节点",[1091,1779,1780],{},"讲完了查找的概念之后，我们一起来看看二叉查找树的查找操作的代码实现",[1233,1782,1785],{"className":1783,"code":1784,"language":1451,"meta":1239},[1449],"\n\u002F**\n * 在二叉查找树中查找指定值的节点\n * @param tree 二叉查找树的根节点\n * @param data 要查找的数据值\n * @return 找到的节点指针，如果未找到则返回NULL\n *\u002F\nTreeNode* find(TreeNode* tree, int data) {\n    \u002F\u002F 从根节点开始遍历\n    TreeNode* current = tree;\n\n    \u002F\u002F 当当前节点不为空时继续查找\n    while (current != NULL) {\n        \u002F\u002F 如果要查找的值小于当前节点值，在左子树中查找\n        if (data \u003C current->data) {\n            current = current->left;\n        }\n        \u002F\u002F 如果要查找的值大于当前节点值，在右子树中查找\n        else if (data > current->data) {\n            current = current->right;\n        }\n        \u002F\u002F 如果值相等，找到了目标节点\n        else {\n            return current;\n        }\n    }\n\n    \u002F\u002F 未找到目标节点\n    return NULL;\n}\n\n",[1241,1786,1784],{"__ignoreMap":1239},[1095,1788,1790],{"id":1789},"二叉查找树的插入操作",[1106,1791,1789],{},[1091,1793,1794],{},"插入跟查找差不多，也是从根节点开始找，如果要插入的数据比节点的数据大，并且节点的右子树为空，就将新数据直接插到右子节点的位置；如果不为空，就再递归遍历右子树，查找插入位置。同理，如果要插入的数据比节点数值小，并且节点的左子树为空，就将新数据插入到左子节点的位置；如果不为空，就再递归遍历左子树，查找插入位置。",[1091,1796,1797],{},"假设我们要插入 63 ，我们用一张动态图来看看插入的流程。",[1091,1799,1800],{},[1646,1801],{"alt":1648,"src":1802},"https:\u002F\u002Fpica.zhimg.com\u002Fv2-a3bb96d446f90e825f758a560e740f8a_b.webp",[1110,1804,1805,1808,1811],{},[1113,1806,1807],{},"1、63 > 62 ，在树的右子树继续查找.",[1113,1809,1810],{},"2、63 \u003C 88 ，在树的左子树继续查找",[1113,1812,1813],{},"3、63 \u003C 73 ,因为 73 是叶子节点，所以 63 就成为了 73 的左子树。",[1091,1815,1816],{},"我们来看看二叉查找树的插入操作实现代码",[1233,1818,1821],{"className":1819,"code":1820,"language":1451,"meta":1239},[1449],"\u002F**\n * 在二叉查找树中查找指定值的节点\n * @param tree 二叉查找树的根节点\n * @param data 要查找的数据值\n * @return 找到的节点指针，如果未找到则返回NULL\n *\u002F\nTreeNode* find(TreeNode* tree, int data) {\n    \u002F\u002F 从根节点开始遍历\n    TreeNode* current = tree;\n\n    \u002F\u002F 当当前节点不为空时继续查找\n    while (current != NULL) {\n        \u002F\u002F 如果要查找的值小于当前节点值，在左子树中查找\n        if (data \u003C current->data) {\n            current = current->left;\n        }\n        \u002F\u002F 如果要查找的值大于当前节点值，在右子树中查找\n        else if (data > current->data) {\n            current = current->right;\n        }\n        \u002F\u002F 如果值相等，找到了目标节点\n        else {\n            return current;\n        }\n    }\n\n    \u002F\u002F 未找到目标节点\n    return NULL;\n}\n",[1241,1822,1820],{"__ignoreMap":1239},[1095,1824,1826],{"id":1825},"二叉查找树的删除操作",[1106,1827,1825],{},[1091,1829,1830],{},"删除的逻辑要比查找和插入复杂一些，删除分一下三种情况：",[1091,1832,1833,1836],{},[1106,1834,1835],{},"「第一种情况」","：如果要删除的节点没有子节点，我们只需要直接将父节点中，指向要删除节点的指针置为 null。比如图中的删除节点 51。",[1091,1838,1839,1842],{},[1106,1840,1841],{},"「第二种情况」","：如果要删除的节点只有一个子节点（只有左子节点或者右子节点），我们只需要更新父节点中，指向要删除节点的指针，让它指向要删除节点的子节点就可以了。比如图中的删除节点 35。",[1091,1844,1845,1848],{},[1106,1846,1847],{},"「第三种情况」","：如果要删除的节点有两个子节点，这就比较复杂了。我们需要找到这个节点的右子树中的最小节点，把它替换到要删除的节点上。然后再删除掉这个最小节点，因为最小节点肯定没有左子节点（如果有左子结点，那就不是最小节点了），所以，我们可以应用上面两条规则来删除这个最小节点。比如图中的删除节点 88",[1091,1850,1851],{},"前面两种情况稍微简单一些，第三种情况，我制作了一张动态图，希望能对你有所帮助。",[1091,1853,1854],{},[1646,1855],{"alt":1648,"src":1856},"https:\u002F\u002Fpicx.zhimg.com\u002Fv2-ee38bef7b1b648d935dfa0c4cc0882c5_b.webp",[1091,1858,1859],{},"我们来看看二叉查找树的删除操作实现代码",[1233,1861,1864],{"className":1862,"code":1863,"language":1451,"meta":1239},[1449],"void delete(TreeNode** tree, int data) {\n    TreeNode* p = *tree; \u002F\u002F p指向要删除的节点，初始化指向根节点\n    TreeNode* pp = NULL; \u002F\u002F pp记录的是p的父节点\n    while (p != NULL && p->data != data) {\n        pp = p;\n        if (data > p->data) p = p->right;\n        else p = p->left;\n    }\n    if (p == NULL) return; \u002F\u002F 没有找到\n\n    \u002F\u002F 要删除的节点有两个子节点\n    if (p->left != NULL && p->right != NULL) { \u002F\u002F 查找右子树中最小节点\n        TreeNode* minP = p->right;\n        TreeNode* minPP = p; \u002F\u002F minPP表示minP的父节点\n        while (minP->left != NULL) {\n            minPP = minP;\n            minP = minP->left;\n        }\n        p->data = minP->data; \u002F\u002F 将minP的数据替换到p中\n        p = minP; \u002F\u002F 下面就变成了删除minP了\n        pp = minPP;\n    }\n\n    \u002F\u002F 删除节点是叶子节点或者仅有一个子节点\n    TreeNode* child; \u002F\u002F p的子节点\n    if (p->left != NULL) child = p->left;\n    else if (p->right != NULL) child = p->right;\n    else child = NULL;\n\n    if (pp == NULL) *tree = child; \u002F\u002F 删除的是根节点\n    else if (pp->left == p) pp->left = child;\n    else pp->right = child;\n\n    free(p); \u002F\u002F 释放被删除节点的内存\n}\n",[1241,1865,1863],{"__ignoreMap":1239},[1091,1867,1868],{},"二叉查找树在极端情况下会退化成链表，例如每个节点都只有一个左节点，这是时间复杂度就变成了 O(n)，为了避免这种情况，又出现了一种新的树叫「平衡二叉查找树」，之后再开坑讲",[1091,1870,1871],{},"还有个前缀树，之后也会开坑讲一下",{"title":1239,"searchDepth":1873,"depth":1873,"links":1874},4,[1875,1877,1878,1879,1884,1890,1895,1896,1897,1898],{"id":1097,"depth":1876,"text":1098},2,{"id":1130,"depth":1876,"text":1130},{"id":1294,"depth":1876,"text":1294},{"id":364,"depth":1876,"text":364,"children":1880},[1881,1883],{"id":1393,"depth":1882,"text":1396},3,{"id":1405,"depth":1882,"text":1408},{"id":1417,"depth":1876,"text":1417,"children":1885},[1886,1887,1888,1889],{"id":1425,"depth":1882,"text":1425},{"id":1429,"depth":1882,"text":1429},{"id":1516,"depth":1882,"text":1516},{"id":1527,"depth":1882,"text":1527},{"id":1548,"depth":1876,"text":1548,"children":1891},[1892,1893,1894],{"id":1634,"depth":1882,"text":1634},{"id":1661,"depth":1882,"text":1661},{"id":1689,"depth":1882,"text":1689},{"id":1724,"depth":1876,"text":1724},{"id":1746,"depth":1876,"text":1746},{"id":1789,"depth":1876,"text":1789},{"id":1825,"depth":1876,"text":1825},"md",true,{"uuid":1902,"slots":1903},"c9509c90-9d60-11f0-9e9b-879d11968e89",{},{"title":1085,"description":1093},"posts\u002F数据结构\u002F2025-09-29-数据结构-树",[42,363,364],"Mg9ZudrPv9tRz3J2_hh8q_7FBm1nRwK-SXXPcjDK3Jc",1790443288348]