中间的中间规则选取支点元素代码_看完这篇文章,别再说二叉树了,树根都给你拔起来了(图解+代码+详细思路)...

欢迎关注微信公众号:简说Python关注后回复:1024,可以领取学习资源。

这两天和几个朋友组了个互相督促学习群,想着督促一下自己学习,也督促自己的原创输出,其实很多时候都是懒,真不是没有东西可以写了,这不,我在我的免费知识星球简说编程里开了个新的标签日常编程问题,后面我会把自己学习工作中遇到的一些问题和解决方法记录到里面,有些可以扩展的点,我会写到微信公众号里。我定的目标是:

cd20980cb1a51cae1627471c4a7a7635.png

我简单写了个规则,大家说可以,然后,我们就开始吧,我习惯把该做的事情提前一天做(如果有时间的话)。

0f1fccf4e9c9ce4d0aa6bbd8e38dfd9f.png

今天给大家分享的书籍《Python程序员面试算法宝典》第三章第一小节:什么是二叉树,还介绍了常用的二叉树遍历方法,以及如何做算法题的实战方法。

如果你是第一次看,也许,你可以看看本系列下面的文章:

Python数据结构:链表合集(12+7),复现几遍,包你学会

Python数据结构:栈队列哈希合集(10+1),复现几遍,包你学会

不敲代码,5分钟带你认识二叉树

今日问题

"""
目标:写一个程序,将一个有序数组存放到二叉树中

输入:[1, 2, 3, 4, 5, 6, 7]
输出:4
/ \
2 6
/ \ / \
1 3 5 7

Goal: write a program to store an ordered array in a binary tree
Input: [1, 2, 3, 4, 5, 6, 7]
Output: 4
/ \
2 6
/ \ / \
1 3 5 7
"""

1> 什么是二叉树?

不敲代码,5分钟带你认识二叉树

2> 解题优先

2.1> 思路概述

核心思想:将数组折中分成左右两部分,将中间结点当作二叉树的根结点,左边当作左子树,右边当作右子树,对左右两边数组同样按上面的方法分,要读取时采用中序遍历对二叉 树进行遍历打印。

Core idea: divide the array into left and right parts, regard the
middle node as the root node of the binary tree, the left as the
left subtree, and the right as the right subtree. Divide the left
and right arrays according to the above method, and use the middle
order traversal to print the binary tree when reading.
2.2> 思路图解

1b6d35bcab32fb02142d39f38d401e50.png

2.3> 实现代码
def array_to_binary_tree_one(arr, start, end):
2.4> 测试代码
# 测试转化结果,将转化后的二叉树打印出来
2.5> 运行结果
13f5a763555cb7a7fb8355afaf1ed592.png
与手写该二叉树的中序遍历结果是一致的,无误。

3> 搞就搞通:二叉树的遍历

3.1> 二叉树的遍历概述

通常二叉树的遍历分为深度优先遍历和广度优先遍历,深度优先遍历又包括:前序遍历、中序遍历、后序遍历。

前序遍历 (Pre-Order Traversal)(根结点-左孩子-右孩子)
中序遍历 (In-Order Traversal)(左孩子-根结点-右孩子)
后序遍历 (Post-Order Traversal)(左孩子-右孩子-根结点)

广度优先遍历又称为层次遍历 (Hierarchical traversal)(按二叉树层来遍历)。上面我们已经写了中序遍历,现在我们来仔细看看,看看读取结果。

3.2> 前序遍历 (Pre-Order Traversal)

所谓前序遍历,就是按根结点-左孩子-右孩子的顺序遍历二叉树,每遍历到一个结点,先访问该结点本身(root 根),然后访问该结点左孩子(lchild),对于左孩子也按上面方法访问,然后再访问右孩子(rchild)。

3.2.0> 思路图解
421422cdac1accca7fba0ef3ee45beec.png
3.2.1> 递归实现
def pre_order_traversal(root):
3.2.2> 非递归实现
需要导入我们之前写过的栈,作为临时存储空间。如果你还不知道,不妨看看下面这篇文章:

Smaller Python数据结构:自己动手实现栈

from StackQueueHash.b_1_implementation_stack 
3.3> 中序遍历 (In-Order Traversal)
3.3.0> 思路图解

7c804dd2ff687bb7384bf1603096aee8.png

3.3.1> 递归实现
def in_order_traversal(root):
3.3.2> 非递归实现
需要导入我们之前写过的栈,作为临时存储空间。如果你还不知道,不妨看看下面这篇文章:

Smaller Python数据结构:自己动手实现栈

from StackQueueHash.b_1_implementation_stack 
3.4> 后序遍历 (Post-Order Traversal)
3.4.0> 思路图解
0e2aa8e3bb82a756bb568d8a54d5ef83.png
3.4.1> 递归实现
def post_order_traversal(root):
3.4.2> 非递归实现
需要导入我们之前写过的栈,作为临时存储空间。如果你还不知道,不妨看看下面这篇文章:

Smaller Python数据结构:自己动手实现栈

from StackQueueHash.b_1_implementation_stack 
3.5> 层次遍历 (Hierarchical traversal)
3.5.0> 思路图解

f5cd17e87640c0a54f5adebf848fb2a3.png

3.5.1> 递归实现
def hierarchical_traversal(root, arr, levels):

使用函数装饰器改进代码:

# 思路来源:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/
3.5.2> 非递归实现

为什么下面代码中临时存储结点要用deque双向队列呢?主要是层次遍历中要求要从左往右遍历,所以使用deque可以从头出(popleft),这样操作比单纯操作列表(list)效率要高,所以这里选用了deque。

# 思路来自:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/

今天还是很干的货了,也很花了一些时间整理,一来加深自己印象,再者希望对大家学习二叉树有帮助。难点在二叉树的非递归遍历上,我把代码写的很通俗易懂,想到就写,并且加了大量注释,在变量名、函数名、类名、包名都是严格按照标准写的(代码规范+自己的习惯),可能像白话文一样,里面也有很多可以优化的地方,之所以现在没直接优化,是为了方便大家阅读学习,坚持。

附:不要怕刷算法题,老表教你

如果你看了本文的代码+注释+思路都晦涩难懂的话,我建议你不要只看,可以把电脑拿出来,手机打开简说Python公众号,打开这篇文章,然后用电脑对着文章里的代码一个字一个字的先敲一遍,先不管里面到底说了啥。

第一遍过后,你可能还是觉得索然无味,甚至可能出错,没关系,咱们再来一遍;

第二遍过后,你应该有了些感觉了,不管有没有感觉,你都得开始下一步了,开始跟着注释读代码,在没个你觉得难的代码后面加个print,看看他到底是了啥;

第三遍,这个时候你真的该有点感觉了,趁热打铁,草稿纸拿出来,字再丑,也得画一画,不管你是画符还是画花,都给我在纸上把代码逻辑写一遍(什么逻辑,就是代码每一句做了写啥,干了些啥,那些变量有了变化,变成啥样了) ;

第四遍,也许第三遍你得走好多遍,那都是你的本事,然后也会成为你的成功堡垒的一块砖,再读代码,然后自己在草稿纸上根据自己的思考,对问题的认识,写出你想到的解决方法,记住了,先写思路,然后把思路变成代码,思路也就是伪代码,他告诉你每步该怎么走;

第五遍,把你草稿纸上的代码输入到电脑,运行,验证,改错,有问题重复上面的1-5步;

当然,你还需要会调试代码,这里,我分享了我最长用的三种调试代码的方法,也许对你也有用。一般我感觉代码逻辑比较绕或者难理解的时候,我一般使用三种方法:

1.手写逻辑过程,跟着代码一步一步来

优点:自己主观思考比较多,整个过程下来,基本能搞清楚,还能举一反三 缺点:易出错,耗时长 

比较适合简单的逻辑代码

8d5ada7660e095dd82e845ad70b16b3b.png

2.print实时输出每行代码执行后,所有变量的变化

优点:代码执行过程不需动脑,不会出错

缺点:耗时还是比较长,后面推导过程还得自己一步步来,本质上与方法一无异 

同样适合简单量小的逻辑代码

2c00a29114866cb950c49981ebbe825d.png

3.单步调试,设置断点,跨越式调试

优点:基本上解决前面两种方法的问题 

缺点:耗时(感觉无法避免 除非自己是大神) 

几乎适合所有代码

bb3650390ff6cd1419dbec48c1e1a19f.png

最后,你应该能完成学习,如果完不成,你可以加微信jjxksa888,我的个人微信,一起聊聊你的问题,我们还有学习交流群,供大家交流学习。

有永远的方法论,但坚持才是有效的。

本文代码思路部分来自书籍《Python程序员面试宝典》,书中部分代码有问题,文中已经修改过了,并添加上了丰厚的注释,方便大家学习,后面我会把所有内容开源放到Github上,包括代码,思路,算法图解(手绘或者电脑画),时间充裕的话,会录制视频。希望大家多多支持。

大家好,我是老表 觉得本文不错的话,转发、留言、点赞,是对我最大的支持。

欢迎关注微信公众号:简说Python 关注后回复:1024,可以领取精选学习资源。

每日 留言 说说你读完本文感受? 或者一句激励自己的话? (字数不少于15字) 留言赠书 《Python程序员面试算法宝典》是一本讲解程序员面试笔试算法的书,代码采用Python语言编写,书中除了讲解如何解答算法问题以外,还引入了例子辅以说明,让读者更容易理解。本书几乎将程序员面试笔试过程中算法类真题一网打尽,在题目的广度上,通过各种渠道,搜集了近3年来几乎所有IT企业面试笔试算法的高频题目,所选择题目均为企业招聘使用题目。

6e605b88f366891b5581516a48fd8f28.png

扫码查看书籍详情 留言赠书:《Python程序员面试算法宝典》 怎么 加入 刻 意 学 习队 伍 点我,看文末彩蛋 留言 有啥 福利 点我就知道了 想进学 习交流 群 加 微信: jjxksa888 :简说Python 2小时快速掌握Python基础知识要点

完整Python基础知识要点

Python小知识 | 这些技能你不会?(一) Python小知识 | 这些技能你不会?(二) Python小知识 | 这些技能你不会?(三) Python小知识 | 这些技能你不会?(四) 点 在看 ,是你自己的选择 转发 ,也是你自己的选择 也许,可以证明你 看过 也许,可以证明你 学了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值