链表中常见的使用方法逻辑整理

news2024/12/23 10:05:39

文章目录

  • 1. 二叉树特点
    • 1.1 完全二叉树
    • 1.2 满二叉树
  • 2. 二叉树创建
    • 2.1 通过先序序列带有叶子结点标识符创建二叉树
    • 2.2 通过层次遍历顺序创建二叉树
    • 2.3 通过 先序+中序 创建二叉树
    • 2.4 通过 先序+中序 创建二叉树
    • 2.5 通过 中序+后序 创建二叉树
  • 3. 二叉树遍历通用方法
    • 3.1 先序遍历(深度递归)
    • 3.2 中序遍历(深度递归)
    • 3.3 后序遍历(深度递归)
    • 3.4 广度优先遍历(BFS)
  • 4. 常见面试题
    • 4.1 二叉树的中序遍历
    • 4.2 二叉树的最大深度
    • 4.3 翻转二叉树
    • 4.4 对称二叉树
    • 4.5 二叉树的直径
    • 4.6 二叉树的层序遍历
    • 4.7 将有序数组转换为二叉搜索树
  • 5. 参考文档

二叉树常见的使用方法逻辑整理


1. 二叉树特点

二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。

二叉树特点

  • 性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)
  • 性质2: 深度为k的二叉树至多有2^k - 1个结点(k>0)
  • 性质3: 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
  • 性质4:具有n个结点的完全二叉树的深度必为 log2(n+1)
  • 性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外)

1.1 完全二叉树

完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。

在这里插入图片描述

1.2 满二叉树

除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。

在这里插入图片描述

2. 二叉树创建

class Node():
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        

class Tree():
    def __init__(self):
        self.root = None
        self.queue = [] #用来存放正在操作的三个树节点,分别是root,left和right
        self.create_queue = [] #用来存放先序序列来创建二叉树

2.1 通过先序序列带有叶子结点标识符创建二叉树

#通过先序序列创建二叉树,没有左右子节点被标记为'#'
def createTree(self):
    current = self.create_queue.pop(0)
    if current != '#':
        new_node = Node(current)
        if self.root is None:
            self.root = new_node
        new_node.left = self.createTree()
        new_node.right = self.createTree()
        return new_node
    return None

2.2 通过层次遍历顺序创建二叉树

#通过层次遍历顺序创建二叉树
def add(self, val):
    new_node = Node(val)
    self.queue.append(new_node)
    if self.root is None:
        self.root = new_node
        return 
    tree_node = self.queue[0]
    if tree_node.left is None:
        tree_node.left = new_node
    else:
        tree_node.right = new_node
        self.queue.pop(0)

2.3 通过 先序+中序 创建二叉树

#通过前序序列和中序序列创建二叉树
def create_tree(self, pre_order, mid_order):
    if len(pre_order) == 0:
        return None
    new_node = Node(pre_order[0])
    if self.root is None:
        self.root = new_node
    i = mid_order.index(pre_order[0])
    print(i)
    new_node.left = self.create_tree(pre_order[1:1+i], mid_order[:i])
    new_node.right = self.create_tree(pre_order[1+i:], mid_order[i+1:])
    return new_node

2.4 通过 先序+中序 创建二叉树

#通过前序序列和中序序列创建二叉树
def create_tree(self, pre_order, mid_order):
    if len(pre_order) == 0:
        return None
    new_node = Node(pre_order[0])
    if self.root is None:
        self.root = new_node
    i = mid_order.index(pre_order[0])
    print(i)
    new_node.left = self.create_tree(pre_order[1:1+i], mid_order[:i])
    new_node.right = self.create_tree(pre_order[1+i:], mid_order[i+1:])
    return new_node

2.5 通过 中序+后序 创建二叉树

#通过中序和后序创建二叉树
def construct_tree(self, mid_order, post_order):
    length = len(post_order)
    if length == 0:
        return None
    new_node = Node(post_order[-1])
    if self.root is None:
        self.root = new_node
    i = mid_order.index(post_order[-1])
    new_node.left = self.construct_tree(mid_order[:i], post_order[:i])
    new_node.right = self.construct_tree(mid_order[i+1:], post_order[length-2-i:length-1])
    return new_node

3. 二叉树遍历通用方法

二叉树的遍历方式通常有2种

  • 深度搜索(dfs):先序遍历、中序遍历、后序遍历
  • 广度搜索(bfs): 广度优先遍历

针对深度搜索的3种方式,对应的访问路径不同,需要根据实际情况进行调整

3.1 先序遍历(深度递归)

#通过递归进行先序遍历
def dfs(self, root):
    if root is None: return
    print(root.val)
    self.recursion_vlr(root.left)
    self.recursion_vlr(root.right)

遍历顺序:根节点→左孩子→右孩子,注意所有子树都是按照该顺序访问

在这里插入图片描述

3.2 中序遍历(深度递归)

#通过递归进行中序遍历
def dfs(self, root):
    if root is None: return
    self.recursion_lvr(root.left)
    print(root.val)
    self.recursion_lvr(root.right)

遍历顺序:左孩子→根节点→右孩子,注意所有子树都是按照该顺序访问

在这里插入图片描述

3.3 后序遍历(深度递归)

#通过递归进行后序遍历
def dfs(self, root):
    if root is None: return
    self.recursion_lrv(root.left)
    self.recursion_lrv(root.right)
    print(root.val)

遍历顺序:左孩子→根节点→右孩子,注意所有子树都是按照该顺序访问

在这里插入图片描述

3.4 广度优先遍历(BFS)

#利用队列进行广度优先遍历BFS
def bfs(self):
    queue = []
    current = self.root
    queue.append(current)
    while queue:
        current = queue.pop(0)
        print(current.val)
        if current.left: queue.append(current.left)
        if current.right: queue.append(current.right)

4. 常见面试题

一些总结

4.1 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """

        rs = []
        def dfs(root, res):
            if root is None:
                return 
            
            dfs(root.left,res)
            res.append(root.val)
            dfs(root.right,res)
        
        dfs(root, res)
        return res 

4.2 二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:3
示例 2:

输入:root = [1,null,2]
输出:2

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if root is None: return 0
        left_height = self.maxDepth(root.left)
        right_height = self.maxDepth(root.right)
        return max(left_height, right_height) + 1
        

4.3 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:

在这里插入图片描述

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:

在这里插入图片描述

输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:return None
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root 

4.4 对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

在这里插入图片描述

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

在这里插入图片描述

输入:root = [1,2,2,null,3,null,3]
输出:false

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:return True
        def dfs(left, right):
            if not (left or right): return True
            if not (left and right): return False
            if left.val != right.val: return False
            return dfs(left.right, right.left) and dfs(left.left, right.right)
        return dfs(root.left, root.right)

4.5 二叉树的直径

给你一棵二叉树的根节点,返回该树的 直径 。

在这里插入图片描述

二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。

两节点之间路径的 长度 由它们之间边数表示。

示例 1:

在这里插入图片描述

输入:root = [1,2,3,4,5]
输出:3
解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。

示例 2:

输入:root = [1,2]
输出:1

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def diameterOfBinaryTree(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        self.res = 1
        def dfs(root):
            if root is None: return 0 
            l = dfs(root.left)
            r = dfs(root.right)
            self.res = max(self.res, l + r + 1)
            return max(l,r) + 1
        
        dfs(root)
        return self.res -1

4.6 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:

输入:root = [1]
输出:[[1]]
示例 3:

输入:root = []
输出:[]

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        res = []
        if not root: return res
        
        queue = [root]
        while queue:
            size = len(queue)
            tmp = []
            for _ in range(0, size):
                r = queue.pop(0)
                tmp.append(r.val)
                if r.left: queue.append(r.left)
                if r.right: queue.append(r.right)
            res.append(tmp)
        return res

4.7 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵平衡二叉搜索树。

示例 1:

在这里插入图片描述

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

在这里插入图片描述

示例 2:

在这里插入图片描述

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution(object):
    def sortedArrayToBST(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        def dfs(nums, low, high):
            if(low > high): return 
            
            # 以中间树作为根
            mid = low + (high - low) /2 
            root = TreeNode(nums[mid])
            root.left = dfs(nums, low, mid - 1)
            root.right = dfs(nums, mid + 1, high)
            return root
        
        return dfs(nums, 0, len(nums) - 1)

5. 参考文档

暂无,相关面试题请参考letcode以及相关说明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1592403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【软考中级】软件设计师考点分布

文章目录 软考官网资格设置软考报考流程 【软件设计师】考点分布选择题考点分布案例题考点分布 软考官网 中国计算机技术职业资格网:https://www.ruankao.org.cn/ 官网报名平台:https://bm.ruankao.org.cn/sign/welcome 资格设置 计算机软件计算机网…

SSM整合配置案例

一、什么是SSM整合 SSM整合用到两个容器,web容器是root容器的子容器,父子容器关系。 为了方便编写,我们可以三层架构每层对应一个配置类,分别指定两个容器加载 Ioc如何初始化? 二、简单实现整合SSM (一…

是的,本科毕业八年,我考研了

今天,是一篇纯分享文。 是的,本科毕业八年,我考研了。 停更10个月,历时296天,我考研上岸了。 小伙伴们,好久不见。 一 发今年第一篇文章的时候刚处理完后续事宜,就简单说了句,后台…

QThread的学习

锁住该线程直到下面的情况之一出现: (1)和该线程连接的对象已经执行完成(例如:当它从run()中返回时) 如果该线程已经结束,该函数将返回true。 如果该线程还没有开始,它也返回true。 (2)time毫秒已经过去。如…

Linux 内核学习(2) --- regulator 框架

目录 Regulator 介绍Regulator provider 注册struct regulator_descstruct regualtor_configDTS 配置和解析On BoardConfig 配置regulator_ops总结 Regulator Consumer 使用struct regulator 获取regulator 操作使用Multi Regulator 参考博客 Regulator 介绍 Regulator 指的是…

电子烟特效音语音方案选型-WTN6020-8S-E

随着科技的迅猛进步,电子烟行业亦在持续创新与突破,引领着全新的潮流。其中,电子烟产品所特有的吸烟声音特效播报功能,无疑成为了技术革新的璀璨亮点。这一设计巧妙地将吸烟的声效融入使用体验中,使得用户在吸电子烟时…

Javascript 斐波那契搜索-迭代与递归(Fibonacci Search)

给定一个大小为 n 的排序数组 arr[] 和要在其中搜索的元素 x。如果 x 存在于数组中,则返回 x 的索引,否则返回 -1。 例子: 输入: arr[] {2, 3, 4, 10, 40}, x 10输出: 3 元素 x 出现在索引 3 处。 输入&#xff1…

HarmonyOS开发实例:【app帐号管理】

应用帐号管理 介绍 本示例选择应用进行注册/登录,并设置帐号相关信息,简要说明应用帐号管理相关功能。效果图如下: 效果预览 使用说明参考鸿蒙文档:qr23.cn/AKFP8k点击或者转到。 1.首页面选择想要进入的应用,首次进…

【Redis】持久化

文章目录 一、RDB1.1、RDB的自动备份与手动备份1.1.1、自动备份1.1.2、手动备份 1.2、RDB优点1.3、RDB缺点1.4、RDB快照1.5、RDB优化配置项 二、AOF2.1、AOF工作流程2.2、AOF写回策略2.3、MP-AOF实现2.4、AOF优缺点2.5、AOF重写机制 三、RDBAOF混合持久化3.1、数据恢复顺序和加…

生产环境中秒杀接口并发量剧增与负载优化策略探讨

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 目录 引言 1. 实施限流措施 1.1 令牌桶算法: 1.2 漏…

如何申请阿里云服务器学生优惠,入口在这呢!

阿里云学生服务器免费申请,之前是云翼计划学生服务器9元/月,现在是高校计划,学生服务器可以免费申请,先完成学生认证即可免费领取一台云服务器ECS,配置为2核2G、1M带宽、40G系统盘,在云服务器ECS实例过期之…

什么是队头阻塞以及如何解决

前言 通常我们提到队头阻塞,指的可能是TCP协议中的队头阻塞,但是HTTP1.1中也有一个类似TCP队头阻塞的问题,下面各自介绍一下。 TCP队头阻塞 队头阻塞(head-of-line blocking)发生在一个TCP分节丢失,导致…

ip地址切换器安卓版,保护隐私,自由上网

在移动互联网时代,随着智能手机和平板电脑的普及,移动设备的网络连接变得愈发重要。为了满足用户在不同网络环境下的需求,IP地址切换器安卓版应运而生。本文将以虎观代理为例,为您详细解析IP地址切换器安卓版的功能、应用以及其所…

26、链表-环形链表II

思路: 这道题就是判断链表中是否有环,首先使用集合肯定可以快速地解决,比如通过一个set集合遍历,如果遍历过程中有节点在set中已经存在那么说明存在环。返回这个节点即可 第二种方式就是通过快慢指针方式寻找环。如何做呢&#xf…

震惊!借助Coze白嫖GPT4-128k解决方案

震惊!某大佬借助Coze白嫖GPT4-128k解决方案 前言 此文章介绍如何免费使用GPT-4高级模型并拓展API功能 最近的 Coze 在国内开放了,可以免费使用大模型。但是和国外的有点区别,国外版本使用的chatgpt4,国内版本使用的是语雀大模型。 Coze是一…

《前端防坑》- JS基础 - 你觉得typeof nullValue === null 么?

问题 JS原始类型有6种Undefined, Null, Number, String, Boolean, Symbol共6种。 在对原始类型使用typeof进行判断时, typeof stringValue string typeof numberValue number 如果一个变量(nullValue)的值为null,那么typeof nullValue "?" const u …

图书推荐:用ChatGPT获取在线被动收入的8个方法

Universe S. The ChatGPT Money Mastery. Unlocking Online Income..for Dummies 2023 想要彻底革新您的收入模式吗?《用ChatGPT获取在线被动收入的8个方法》一书是您不可错过的指南。 在这个数字化飞速发展的时代,人工智能成为了开启成功之门的钥匙。…

2024年广东省网络系统管理样题第1套网络搭建部分

2024年广东省职业院校技能大赛样题1 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书,赛题,解析等资料,知识点培训服务 添加博主wx:liuliu5488233 网络系统管理赛项 模块A:网络…

操作系统(第四周 第二堂)

目录 回顾 进程运行 进程的创建 进程的工作 举例 进程的删除 举例1(走到return 0结束) 举例2(利用exit(1)结束) 进程通信 共享内存 生产者算法 消费者算法 消息传递 定义 算法实现 总结 回顾…

数据结构--链式队列

一.链式队列的设计思想: 首先一定要理解设计的初衷,就是队头队尾的位置要满足怎么快怎么设计.那么分析如下: 最终我们敲定了入队,出队的时间复杂度都为O(1)的一种设计,也就是第四种设计;当然,头节点的数据域不使用,所以我们设计链式队列的头节点的时候删除数据域即可,链式队列…