IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python实现线索二叉树(以先序线索化为例) -> 正文阅读

[Python知识库]python实现线索二叉树(以先序线索化为例)

背景

给定一棵树中的某一个节点,让你找出这个节点的先序遍历的直接前驱,如果是一颗普通的树,因为指向的单向性,你只能建立两个指针pre,cur_node,pre紧接在cur_node的后面,从头遍历到尾,如果cur_node指向了要找的节点,那么pre就是要找的节点的直接前驱。

可以看到,无论给定的节点在哪里,都需要从根节点开始从头遍历,所以效率是非常低的。

节点的定义

class TreeNode:
    def __init__(self, val=None, left=None, right=None, ltag=0, rtag=0):
        self.val = val  # 值
        self.left = left  # 左孩子
        self.right = right  # 右孩子
        self.ltag = ltag  # 初始值为0 为0说明指向左孩子,为1说明指向直接前驱
        self.rtag = rtag  # 初始值为0 为0说明指向右孩子,为1说明指向直接后继

构建一颗树

# 创建一颗二叉树(层次遍历)
def create_tree(li):
    if not li: return TreeNode()
    root = TreeNode(li[0])
    cur_que = deque()
    cur_que.append(root)
    li = li[1:][::-1]
    while len(cur_que):
        cur_node = cur_que.popleft()
        if li:
            cur_node.left = TreeNode(li.pop())
            cur_que.append(cur_node.left)

        if li:
            cur_node.right = TreeNode(li.pop())
            cur_que.append(cur_node.right)
    return root

先序遍历线索化

# 先序遍历
def travel(root):
    if root:
        vist(root)
        global pre
        pre = root  # 更新前驱
        if root.ltag == 0:  # 如果是左孩子就访问
            travel(root.left)

        if root.rtag == 0:  # 如果是右孩子就访问
            travel(root.right)

线索化的核心

# 访问当前节点
def vist(cur_node):
    global pre
    if pre:
        if not cur_node.left:  # 当前节点没有左孩子,且前驱pre不为空
            cur_node.left = pre  # 指向它的直接前驱
            cur_node.ltag = 1  # 标记当前左指针指向的是直接前驱
        if not pre.right and cur_node:  # pre没有右孩子 且cur_node不为空
            pre.right = cur_node  # cur_node就是pre的直接后继
            pre.rtag = 1  # 标记当前右指针指向的是直接后继

测试

# 线索化
def thread_tree(root):
    global pre  # 设为全局变量 一开始指向None
    pre = None
    travel(root)
    return root


if __name__ == '__main__':
    root = create_tree(['A', 'B', 'C', 'D', 'E', 'F', 'G'])
    thread_tree(root)

这里使用Tutor进行了运行过程的可视化,最终结果如下(符合预期):

同步更新于个人博客系统:python实现线索二叉树(以先序线索化为例)

源码

# -*- coding: UTF-8 -*-
'''
   *****************LLL*********************
   * @Project :leetcode                       
   * @File    :lll97_二叉树的线索化.py                  
   * @IDE     :PyCharm             
   * @Author  :LLL                         
   * @Date    :2022/5/16 10:30             
   *****************************************
'''
from collections import deque


class TreeNode:
    def __init__(self, val=None, left=None, right=None, ltag=0, rtag=0):
        self.val = val  # 值
        self.left = left  # 左孩子
        self.right = right  # 右孩子
        self.ltag = ltag  # 初始值为0 为0说明指向左孩子,为1说明指向直接前驱
        self.rtag = rtag  # 初始值为0 为0说明指向右孩子,为1说明指向直接后继


# 创建一颗二叉树(层次遍历)
def create_tree(li):
    if not li: return TreeNode()
    root = TreeNode(li[0])
    cur_que = deque()
    cur_que.append(root)
    li = li[1:][::-1]
    while len(cur_que):
        cur_node = cur_que.popleft()
        if li:
            cur_node.left = TreeNode(li.pop())
            cur_que.append(cur_node.left)

        if li:
            cur_node.right = TreeNode(li.pop())
            cur_que.append(cur_node.right)
    return root


# 访问当前节点
def vist(cur_node):
    global pre
    if pre:
        if not cur_node.left:  # 当前节点没有左孩子,且前驱pre不为空
            cur_node.left = pre  # 指向它的直接前驱
            cur_node.ltag = 1  # 标记当前左指针指向的是直接前驱
        if not pre.right and cur_node:  # pre没有右孩子 且cur_node不为空
            pre.right = cur_node  # cur_node就是pre的直接后继
            pre.rtag = 1  # 标记当前右指针指向的是直接后继


# 先序遍历
def travel(root):
    if root:
        vist(root)
        global pre
        pre = root  # 更新前驱 pre总是等于上一轮的root
        if root.ltag == 0:  # 如果是左孩子就访问
            travel(root.left)

        if root.rtag == 0:  # 如果是右孩子就访问
            travel(root.right)


# 线索化
def thread_tree(root):
    global pre  # 设为全局变量 一开始指向None
    pre = None
    travel(root)
    return root


if __name__ == '__main__':
    root = create_tree(['A', 'B', 'C', 'D', 'E', 'F', 'G'])
    thread_tree(root)

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 18:55:28  更:2022-05-21 18:57:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 15:27:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计