【魔兽学霸】阿尔萨斯怒刷食尸鬼二叉树

前言

前端新人第一次写文章 (整活),半娱乐性质文章,写了很久呢,望大家多包涵(轻喷,俺玻璃心)~

孩子算法老是记不住,比如连「二叉树 」的「递归前序遍历」都记不住怎么写,面试又怕不小心写错,于是我衍生出了一个想法,能不能采用游戏短剧的方式来把算法具像化。

特别是对于前端而言,面试里算法很少,都是常见题,我们更加需要会写这些题!

果然,我现在满脑子都是二叉树,再也不怕记不住算法了! 以前序遍历来说,别再去记什么「中左右」之类的,哪有什么「中」,个人感觉其实是不对的,应该叫「处理当前,先左后右」。

本文讲述了「阿尔萨斯」通过「递归」+「前序遍历」的方式来打败「食尸鬼二叉树」,最后却因得不到「点赞」饿晕在路边的故事。

斥候来报,发现!食尸鬼二叉树!

某日,洛丹伦城外发现一颗「食尸鬼二叉树」。

「阿尔萨斯」当即表示从未听过什么「食尸鬼二叉树」。

那其实「食尸鬼二叉树」就是由若干个「食尸鬼节点」构成的。每个「食尸鬼节点」屁股的左边或者右边都连着另外一个「食尸鬼节点」,也可能没有连,就像下面这样。

不就清理食尸鬼吗,小菜一碟!

但「泰瑞纳斯」似乎想把这次的试炼作为对「阿尔萨斯」智慧的磨练。

阿尔萨斯:我******

冲突!激战食尸鬼二叉树!

「阿尔萨斯」来到城外,巧遇「神秘持剑男」。

「神秘持剑男」教会了「阿尔萨斯」「镜像」技能。

食尸鬼二叉树长这样

「阿尔萨斯」通过兵书知道了什么叫作「前序遍历」,无非就是牢记三个步骤:

  1. 打倒面前的食尸鬼;
  2. 跑去左边看看有没有食尸鬼;
  3. 再跑去右边看看有没有食尸鬼。

「阿尔萨斯」立刻来到食尸鬼面前开始行动,按照兵法所说,先打败面前的食尸鬼。

接着,「阿尔萨斯」使用刚刚偷学的「镜像」分出了2个「阿尔萨斯」,以及达拉然最新科技「电话」去 call 「左边」的分身,问他食尸鬼清理完了吗?

分身看到自己面前有一只「食尸鬼」,不敢妄下定论,继续重复兵法里的步骤,先打败面前的食尸鬼,然后分身也再次使用镜像,派遣新的分身去左边看看有无「食尸鬼」。

那有人就问了,为什么这个分身要使用镜像呢?因为对于「食尸鬼二叉树」来说,只要当前位置有「食尸鬼」,那就说明它的屁股左边 或者没有食尸鬼,那么就必须再派新的分身去探查。

那如果探查完发现面前没有食尸鬼了,说明这里就安全了,分身的使命就完成啦,可以消失咯~

左边的分身任务完成了,就可以开始给右边的分身「打电话」了,右边的分身也是重复一样的步骤。

一直以此类推

最终「阿尔萨斯」就消灭了全部的食尸鬼。

那代码怎么写呢?

我们先来打开 leetcode 144题「二叉树的前序遍历」

首先,「泰瑞纳斯」给「阿尔萨斯」打电话,告诉了他第一只「食尸鬼」的位置。

javascript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    // root 相当于食尸鬼二叉树里,第一个食尸鬼的位置
    // 那么「泰瑞纳斯」首先给「阿尔萨斯」打电话,告诉了他第一只「食尸鬼的」位置
    call(root)
};

那我们来看看打完电话要干什么呢?第一步,干掉食尸鬼!

javascript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    const bag = [] // New: 这是用来收集食尸鬼的背包
    
    function call(node) {
        bag.push(node.val) // New: 第一步,干掉食尸鬼,就把它装进我们的包包里吧~
    }
    
    call(root) //「泰瑞纳斯」首先给「阿尔萨斯」打电话,告诉了他第一只「食尸鬼的」位置
};

第二步,派分身去左边探路,给他打电话,让他处理掉那边的食尸鬼。

javascript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    const bag = [] // 这是用来收集食尸鬼的背包
    
    function call(node) {
        bag.push(node.val) // 第一步,干掉食尸鬼,就把它装进我们的包包里吧~
        call(node.left) // New: 第二步,派分身去左边探路,给他打电话
    }
    
    call(root) //「泰瑞纳斯」首先给「阿尔萨斯」打电话,告诉了他第一只「食尸鬼的」位置
};

第三步,派分身去右边探路,也给他打电话,让他处理掉那边的食尸鬼。

javascript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    const bag = [] // 这是用来收集食尸鬼的背包
    
    function call(node) {
        bag.push(node.val) // 第一步,干掉食尸鬼,就把它装进我们的包包里吧~
        call(node.left) // 第二步,派分身去左边探路,给他打电话
        call(node.right) // New: 第三步,派分身去右边探路,给他打电话
    }
    
    call(root) //「泰瑞纳斯」首先给「阿尔萨斯」打电话,告诉了他第一只「食尸鬼的」位置
};

最后,发现没有食尸鬼任务就结束啦~,装着满包的食尸鬼回去交任务吧!

javascript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    const bag = [] // 这是用来收集食尸鬼的背包
    
    function call(node) {
        if (node == null) return // New: 没有食尸鬼就啥都不用干
        bag.push(node.val) // 第一步,干掉食尸鬼,就把它装进我们的包包里吧~
        call(node.left) // 第二步,派分身去左边探路,给他打电话
        call(node.right) // 第三步,派分身去右边探路,给他打电话
    }
    
    call(root) //「泰瑞纳斯」首先给「阿尔萨斯」打电话,告诉了他第一只「食尸鬼的」位置
    
    return bag // New: 回家交差!
};

通过上面这段代码,大家可以发现,在第二步的时候,打电话给分身也会重复执行一样的步骤,实现了递归,也就是一定要左边的「食尸鬼」全部被清理完成后,才会处理右边的「食尸鬼」。

结语

大家喜欢的话,下期尝试来用迭代法做一下中序遍历二叉树吧?感觉迭代法做中序很多小伙伴也是头疼诶!

不知道大家有没有把二叉树的「递归」+「前序遍历」牢记于心了呢?再回忆一遍步骤

  1. 没有食尸鬼就回家;
  2. 打倒面前的食尸鬼,装进包包里;
  3. 打电话给左边看看有没有食尸鬼;
  4. 打电话给右边看看有没有食尸鬼。

洛丹伦的平静离不开「阿尔萨斯」的努力,让我们一起说,「谢谢你,阿尔萨斯」!

对了,「阿尔萨斯」悄悄跟我说他想吃烤肉,现在已经饿晕过去了,看在「阿尔萨斯」这么努力的份上,大家帮帮他吧!

另外,B站还有视频版哦(全是本人配音,包括兽人语,没有用AI语音哈!),更加容易理解。输入框搜索「魔兽学霸」就可以看到了哦~ 求求各位大佬们有币的捧个币场,有赞的捧个赞场,要是是能评论+关注一下我可爱死你们啦~

链接在此:www.bilibili.com/video/BV1Yi...

相关推荐
2401_8572979121 分钟前
秋招内推2025-招联金融
java·前端·算法·金融·求职招聘
通信仿真实验室30 分钟前
MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号
开发语言·算法·matlab
通信仿真实验室35 分钟前
(15)衰落信道模型作用于信号是相乘还是卷积
开发语言·人工智能·算法·matlab
Run with the Wind41 分钟前
【2024.9.29练习】R 格式
算法
Jeremy_1213844 分钟前
三种波束形成方法的区别(MVDR、MMSE以及MSNR波束形成器)
算法
远望樱花兔1 小时前
【d59】【Java】【力扣】146.LRU缓存
java·开发语言·算法
秋夜Autumn1 小时前
贪心算法相关知识
算法·贪心算法
小懒编程日记2 小时前
【数据结构与算法】B树
java·数据结构·b树·算法
心怀花木2 小时前
【算法】双指针
c++·算法
闫铁娃2 小时前
二分解题的奇技淫巧都有哪些,你还不会吗?
c语言·数据结构·c++·算法·leetcode