树在面试中真的是一个出镜率异常高的数据结构了。而且和递归结合紧密,作为手撸代码的考察真是再合适不过。
所以就在这篇日记里不断更新树的一些概念和相应的题目吧~
我的梦想是!一文在手!天下我有!

树的手撸代码中常常涉及到的知识

  • 树的深度

    • 递归 / 非递归
  • 树的高度
    • 递归
    • 非递归: 可以层序
    • 平衡树
  • 树的结点
    • 结点数
    • 求下一个结点:前中后序
  • 数的遍历
    • 前中后序遍历

      • 递归
      • 非递归:栈/队列辅助
    • 层序遍历(队列辅助)
      • 层序遍历一棵树
      • 逐层打印一棵树
      • 之字形打印一棵树等等
    • 前序+中序 / 后序+中序重建一棵树
  • 子树
  • 树的镜像
  • 二叉树
  • 二叉平衡树
    • 左右子树高度差不超过1
  • 二叉搜索树
    • 左子树永远小于等于右子树
  • 树的路径

面试还可能问到

  • 红黑树
  • B树
  • B+树

先写一棵树

你一定要会写树的结点定义啊

# 没有指向老父亲的结点指针的树结点
class TreeNode():def __init__(self,x):self.val = xself.left = Noneself.right = None
# 有指向父亲的结点指针的树结点
class TreeNode2():def __init__(self,x):self.val = xself.left = Noneself.right = Noneself.next = None # 父指针

然后呢?结点写出来了不会写出一棵树来测试自己的代码丢不丢人。。。

# Test:
#        10
#       /  \
#      5   12
#     / \
#    4   7
value = [10,5,12,4,7]
node = []
# 初始化这些结点
for val in value:node.append(TreeNode(val))
# 然后把结点连起来
node[0].left = node[1]
node[0].right = node[2]
node[1].left = node[3]
node[1].right = node[4]# 或者这样
node_var = [10,9,8,7,6,5]
node = []
for item in node_var:node.append(TreeNode(item))i = 0
while 2*i+1<len(node):node[i].left = node[2*i+1]if 2*i+2<len(node):node[i].right = node[2*i+2]i+=1

然后是树的遍历!

这个不管是递归还是非递归,手撸的概率很高。之前阿里的暑期实习就要求我写一个非递归的中序遍历。
非递归可以写出各种版本。但是可以用一个统一的逻辑概括起来。便于记住。如下图所示。

当然还可以有其他逻辑。我就不贴出来了。
太多会乱。统一起来便于记忆!
详细的递归 / 非递归代码如下

class Tranverse():# 递归先序def preOrderIter(self,root):if not root:return []res =[]res.append(root.val)left = self.preOrderIter(root.left)right = self.preOrderIter(root.right)res += left+rightreturn res# 非递归先序# 用一个栈辅助的话,先右孩子在左孩子入栈# 用一个队列,那就pop(0),先左后右def preOrderNoIter(self,root):if not root:return []res =[]stack =[root]while stack:# 元素出栈root = stack.pop()# 访问这个元素res.append(root.val)# 先右if root.right:stack.append(root.right)# 再左if root.left:stack.append(root.left)return res# 递归中序def inOrderIter(self,root):if not root:return []res =[]left = self.inOrderIter(root.left)res += leftres.append(root.val)right = self.inOrderIter(root.right)res += rightreturn res# 非递归中序def inOrderNoIter(self,root):if not root:return []res =[]stack =[]# 如果栈不空或者结点存在while stack or root:#结点存在while root:# 结点入栈并向左子树stack.append(root)root = root.left# 左孩子空了跳出循环。如果栈不空if stack:# 元素出栈并访问root = stack.pop()res.append(root.val)# 然后访问右子树root = root.rightreturn res# 递归后序def postOrderIter(self,root):if not root:return []res =[]left = self.postOrderIter(root.left)right = self.postOrderIter(root.right)res += left+rightres.append(root.val)return res# 非递归后序# 按照根-右-左的顺序存储到res,然后倒序输出# 可以直接对照先序非递归来写def postOrderNoIter1(self,root):if not root:return []stack = [root]res = []while stack:root = stack.pop()# res 存储根res.append(root.val)# 先压栈左孩子,之后会后存入resif root.left:stack.append(root.left)# 后压入右孩子,之后会先弹出先存入resif root.right:stack.append(root.right)return res[::-1]def postOrderNoIter2(self,root):if not root:return []res = []stack =[]while stack or root:while root:stack.append(root)res.append(root.val)root = root.rightif stack:root = stack.pop()root = root.leftreturn res[::-1]# 层序遍历def layerOrder(self,root):if not root:return []res =[]queue =[root]while len(queue)>0:root = queue.pop(0)res.append(root.val)if root.left:queue.append(root.left)if root.right:queue.append(root.right)return res

然后数一下树的结点

其实数树的的结点数有很多办法。
比如可以用任意一种遍历,每次访问一个结点就计数。或者返回结点值列表的长度。
也可以这样直接递归数:

def treeNodeNums(root):if not root:return 0nums = treeNodeNums(root.left)+treeNodeNums(root.right) + 1# 当然这里也可以写:# left = treeNodeNums(root.left)# right = treeNodeNums(root.right)# nums = left+right+1return nums

再然后求一下树的深度

树的深度当然也可以用递归或者非递归方法求。
非递归的话可以借助一下层序遍历
递归的话就很类似于数结点数了:

def treeDepth(root):if not root:return 0# 左子树深度left = treeDepth(root.left)# 右子树深度right = treeDepth(root.right)return max(left,right)+1

【刷题日记】树的那些事儿(一)——基本操作相关推荐

  1. 一个算法笨蛋的12月leetCode刷题日记

    类似文章 一个算法笨蛋的2021年11月leetCode刷题日记 一个算法笨蛋的2021年12月leetCode刷题日记 一个算法笨蛋的2022年1月leetCode刷题日记 一个算法笨蛋的2022年 ...

  2. leetcode刷题之树(三)

    翻转二叉树,感觉做二叉树的问题好像都是那一套公式,除了个别的问题解决不了,用上篇博客leetcode刷题之树(二)的模型基本可以解决.总体来说就是树基本都可以利用递归和迭代的方法去解决,在涉及到树的遍 ...

  3. 菜菜的刷题日记 | 66.加一 Plus One

    系列索引:菜菜的刷题日记 | 被LeetCode用Python狂虐的那段日子 菜鸡的刷题之路--2022/1/7 文章目录 [题目] [我的代码] [参考代码1] [参考代码2] [参考代码3] [思 ...

  4. 牛客刷题日记(2021-12-8)

    牛客刷题日记(2021-12-8) 题目: 以下哪个接口的定义是正确的?( )interface B { void print() { } ;}interface B { static void pr ...

  5. 刷题日记【第十三篇】-笔试必刷题【数根+星际密码+跳台阶扩展问题+快到碗里来】

    刷题日记[第十三篇]-笔试必刷题[数根+星际密码+跳台阶扩展问题+快到碗里来] 1.方法区在JVM中也是一个非常重要的区域,它与堆一样,是被[线程共享]的区域. 下面有关JVM内存,说法错误的是?(c ...

  6. CTFshow刷题日记-MISC-图片篇(上)基础操作和信息附加

    ctfshow 图片篇引语 大部分题目仅涉及单一知识点,但可能有多种解法: 找到flag并不困难,关键是了解每一题背后的原理: 藏在哪?为什么可以这样藏?请多考虑这两个问题: misc脑图-misc之 ...

  7. 牛客刷题日记(2021-11-24)

    牛客刷题日记(2021-11-24) 题目: 下面程序的输出是:() String x="fmn"; x.toUpperCase(); String y=x.replace('f' ...

  8. Leetcode刷题日记(十二)

    又是老台词:欢迎大家来到一晚一度的leetcode刷题日记时间.今天我们来讲讲队列的问题,队列这方面的基础知识需要的同学到博主前面的文章找吧.队列这方面的问题平时博主也是接触得比较少的.下面是一道利用 ...

  9. 菜菜的刷题日记 | 蓝桥杯 — 十六进制转八进制(纯手撕版)附进制转换笔记

    系列索引:菜菜的刷题日记 | 被LeetCode用Python狂虐的那段日子 万万没想到啊,回老家过年断更的几天之后,我会因为无聊在除夕这天做了会儿题,然后写篇题解. 文章目录 [题目] [我的代码] ...

  10. 菜菜的刷题日记 | 12.整数转罗马数字

    系列索引:菜菜的刷题日记 | 被LeetCode用Python狂虐的那段日子 菜鸡的刷题之路--2022/1/24,这几天忙着肝并发编程,题在做但是没空写题解,今晚补一篇. 文章目录 [题目] [官方 ...

最新文章

  1. java程序员学C#基本语法两个小时搞定(对比学习)
  2. SVN禁止提交部分文件
  3. 前端学习(3114):react-hello-对state的理解
  4. logstash安装
  5. then 微信小程序_微信小程序和es6 promise的关系
  6. jQuery easyUI Pagination控件自定义div分页(不用datagrid)
  7. 服务端渲染和客户端渲染区别?
  8. 为什么别人年底购物,同学们年底考证?
  9. 无法将mysql服务器连接到_无法从java连接到mysql服务器
  10. linux监控进程资源,linux系统资源监控命令
  11. in与exist , not in与not exist 的区别
  12. Android复习强化笔记(二)
  13. android 9.0 c7Pro,三星c7pro和vivo x9哪个好?三星Galaxy c7 pro和vivo x9区别对比评测
  14. TensorRt - caffe中支持prelu
  15. 菜鸟学Linux 第041篇笔记 常见系统故障排除
  16. Spark3.0核心调优参数小总结
  17. 解决 1080端口已被占用
  18. 蓝牙SBC开发笔记(一)
  19. 微信服务号认证小程序
  20. 前端最常用的移动App开发方式及技术栈详解

热门文章

  1. Flink使用JdbcSink下沉数据到数据库MySQL
  2. 一种喷涂有可吸收电磁波的水性油漆的飞机外壳
  3. Task04: 文字图例尽眉目(12月datawhale组队)
  4. HTML5七夕情人节表白网页(抖音-罗盘时钟) HTML+CSS+JavaScript 求婚示爱代码 520情人节告白代码 程序员表白源码 3D旋转相册 js烟花代码 css爱心表白
  5. poi-tl生成word文档,java生成word文档
  6. [Vue][面试]你怎么理解vue中的diff算法?
  7. linux中怎么查看stopped进程,Linux下如何查杀stopped进程详解
  8. 061 python实现EXP
  9. 大学生社团管理系统的设计与实现
  10. matlab snr mse,MATLAB 均方根误差MSE、两图像的信噪比SNR、峰值信噪比PSNR、结构相似性SSIM...