二叉树的介绍

学习堆排序时先了解下二叉树,因为堆排序中使用了二叉树。

一、二叉树介绍

二叉树(binary tree)树的每个节点最多有2个孩子节点。注意,这里是最多有2个,也可能只有1个,或者没有孩子节点。

二叉树结构如图
在这里插入图片描述

二叉树还有两种特殊的结构

  1. 满二叉树: 二叉树的所有非叶子节点都存在左右孩子,并且所有叶子节点都在同一层级上,那么这个树就是满二叉树。
    在这里插入图片描述
  2. 完全二叉树:完全二叉树的条件没有满二叉树那么苛刻,满二叉树要求所有分支都是满的;而完全二叉树只需保证最后一个节点之前的节点都齐全即可。
    在这里插入图片描述

二、二叉树的数据结构

二叉树既可以用链表表示也能使用数组来表示。以下是使用Python实现这两种表示方式的示例。

链表表示

在链表表示中,每个节点通常包含三个字段:数据字段,左子节点引用和右子节点引用。我们可以定义一个简单的Node类来表示二叉树的节点,并使用这个类来构建二叉树。
在这里插入图片描述

class Node:  
    def __init__(self, data):  
        self.data = data  
        self.left = None  
        self.right = None  
  
# 示例:创建一个简单的二叉树  
root = Node(1)  
root.left = Node(2)  
root.right = Node(3)  
root.left.left = Node(4)  
root.left.right = Node(5)

数组表示

在数组表示中,对于索引为i的节点,其左子节点的索引为2i+1,右子节点的索引为2i+2(基于0的索引)。
在这里插入图片描述

# 示例:
binary_tree_array = [1, 2, 3, 4, 5, None, 6, None, 8]  # None代表空节点  
  
# 获取左子节点和右子节点的函数  
def get_left_child(parent_index, array):  
    return array[2 * parent_index + 1] if 2 * parent_index + 1 < len(array) else None  
  
def get_right_child(parent_index, array):  
    return array[2 * parent_index + 2] if 2 * parent_index + 2 < len(array) else None  
  
# 示例:访问根节点的左右子节点  
left_child = get_left_child(0, binary_tree_array)  
right_child = get_right_child(0, binary_tree_array)  
print(f"Left child of root: {left_child}")  
print(f"Right child of root: {right_child}")

在实际应用中,链表表示更加灵活,因为用链表表示更加直观,且当树不是完全二叉树时,会浪费存储空间。在Python中,由于链表节点的动态分配和引用关系的灵活性,链表表示更为常见。

三、二叉树的遍历

因为树并不是一个线性结构,所以树的遍历并没有列表那么简单,二叉树的遍历分为以下四种:

  • 前序遍历
  • 中序遍历
  • 后序遍历
  • 层序遍历

前序遍历

遍历规则是:先根节点,再左节点,最后再是右节点。
在这里插入图片描述

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


def preorder_traversal(root):
    if root is None:
        return []
    result = [root.data]
    result += preorder_traversal(root.left)
    result += preorder_traversal(root.right)
    return result


# 示例
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node1.left = node2
node1.right = node3
node2.left = node4
node2.right = node5
node3.right = node6
print("前序遍历:", preorder_traversal(node1))

中序遍历

遍历规则: 先左子树、再根节点、最后右子树。
在这里插入图片描述

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


def inorder_traversal(root):
    if root is None:
        return []
    result = inorder_traversal(root.left)
    result += [root.data]
    result += inorder_traversal(root.right)
    return result


# 示例
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node1.left = node2
node1.right = node3
node2.left = node4
node2.right = node5
node3.right = node6
print("中序遍历:", inorder_traversal(node1))

后序遍历

遍历规则:先左子树、再右子树、最后根节点。
在这里插入图片描述

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


def postorder_traversal(root):
    if root is None:
        return []
    result = postorder_traversal(root.left)
    result += postorder_traversal(root.right)
    result += [root.data]
    return result


# 示例
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node1.left = node2
node1.right = node3
node2.left = node4
node2.right = node5
node3.right = node6
print("后序遍历:", postorder_traversal(node1))

层序遍历

遍历规则:照从根节点到叶子节点的层次关系,一层一层横向遍历各个节点,从上至下,从左至右。
在这里插入图片描述

from collections import deque

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


def levelorder_traversal(root):
    if root is None:
        return []
    result = []
    queue = deque([root])
    while queue:
        level_size = len(queue)
        level_nodes = []
        for _ in range(level_size):
            node = queue.popleft()
            level_nodes.append(node.data)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level_nodes)
    return result


# 示例
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node1.left = node2
node1.right = node3
node2.left = node4
node2.right = node5
node3.right = node6
print("层序遍历:", levelorder_traversal(node1))

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

极客时间: 用 Word2Vec, LangChain, Gemma 模拟全本地检索增强生成(RAG)

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

「 典型安全漏洞系列 」11.身份验证漏洞详解

身份验证是验证用户或客户端身份的过程。网站可能会暴露给任何连接到互联网的人。这使得健壮的身份验证机制成为有效的网络安全不可或缺的一部分。 1. 什么是身份验证 身份验证即认证&#xff0c;是验证给定用户或客户端身份的过程。身份验证漏洞使攻击者能够访问敏感数据和功…

RobotFramework测试框架(12)--第三方库

Library 关于射频指南 |机器人框架 (robotframework.org) 使用RF需要使用Library&#xff0c;常用的第三方库如下&#xff1a; 在web浏览器中进行web应用程序测试可以使用的库是 Selenium Library 在内部使用流行的 Selenium 工具的 Web 测试库Browser Library 由 Playwri…

ThingsBoard通过MQTT发送遥测数据

MQTT基础 客户端 MQTT连接 遥测上传API 案例 MQTT基础 MQTT是一种轻量级的发布-订阅消息传递协议&#xff0c;它可能最适合各种物联网设备。 你可以在此处找到有关MQTT的更多信息&#xff0c;ThingsBoard服务器支持QoS级别0&#xff08;最多一次&#xff09;和QoS级别1&…

【前沿模型解析】潜在扩散模 1 | LDM第一阶段-感知图像压缩总览

文章目录 0 开始~1 感知压缩的目的2 自回归编码器-解码器生成模型一览2.1 AE 自编码器2.2 VAE 变分自编码器2.3 VQ-VAE2.4 VQ-GAN 3 代码部分讲解总览 0 开始~ 从今天起呢&#xff0c;我们会剖析LDM&#xff08;潜在扩散模型&#xff09; 从去年开始&#xff0c;大量的生成模…

蓝桥杯嵌入式(G431)备赛笔记——按键模块设计

目录 cubeMX配置: 代码模板: 最终模板 注意: cubeMX配置: 原理图 引脚配置为上拉模式 定时器 使用定时器3(通用定时器,使用外部晶振,内部时钟),分频系数为80(从0开始则为80-1),则每1s 1m次,定时评率为为10000,对应1s 1m/10000次,频率为10ms每次 一定记得开启…

【SCI绘图】【小提琴系列1 python】绘制按分类变量分组的垂直小提琴图

SCI&#xff0c;CCF&#xff0c;EI及核心期刊绘图宝典&#xff0c;爆款持续更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【小提琴系列1 python】绘制按分类变量分组的垂直小提琴图&#xff0c;文末附完整代码 小提琴图是一种常用的数据可视化工具…

java小作业(4)--编写一个类(第一遍)

1.题目&#xff1a; 2.官方代码&#xff1a; // 宠物基类 class Pet {protected double foodPricePerJin; // 食物单价&#xff08;元/斤&#xff09; protected double foodQuantityPerDay; // 每天所需食物量&#xff08;斤&#xff09; // 计算每天的食物花费 public…

Prefetch

Prefetch &#xff08;<link rel"prefetch">&#xff09; 是一种浏览器优化&#xff0c;它允许我们在需要后续路由或页面之前获取可能需要的资源。可以通过几种方式实现预取。它可以在 HTML 中以声明方式完成&#xff08;例如在下面的示例中&#xff09;&#…

什么是广播系统语言传输指数 STIPA

基础知识 通过广播系统播放一个确定的信号&#xff08;STIPA 测试信号&#xff09;&#xff0c;再在待测点测量其到达后的质量即可。IEC 60268-16 标准中定义通过单一值表示清晰度结果&#xff0c;0 表示完全无法理解&#xff0c;1 表示完美理解。测量单位是 STI&#xff08;语…

Linux文件种类、扩展名与目录配置详解

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、Linux的起源与发展 二、Linux文件种类 1、纯…

Spring的事务详解

Spring的事务详解 一&#xff0c;什么是Spring事务 Spring 事务是 Spring 框架提供的一种对事务进行管理的机制。在使用 Spring 事务时&#xff0c;可以通过注解或编程方式将需要进行事务管理的方法和代码块标记为事务性操作&#xff0c;当这些操作被执行时&#xff0c;Spring…

数据库基础:概念、分类、作用和特点

文章目录 概要DB-Engines 排名数据库的分类数据库的作用数据库的特点数据库的应用小结 概要 数据库是按照数据结构来组织、存储和管理数据的仓库。它是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据库可以被视为电子化的文件柜&#xff0c;用…

详细分析Python爬虫中的xpath(附Demo)

目录 前言1. 基本知识2. 常用API3. 简易Demo 前言 关于爬虫的基本知识推荐阅读&#xff1a;Python爬虫从入门到应用&#xff08;超全讲解&#xff09; 该知识点需要提前安装相关依赖&#xff1a;pip install lxml 1. 基本知识 XPath&#xff08;XML Path Language&#xf…

torchvision中的数据集使用

torchvision中的数据集使用 使用和下载CIFAR10数据集 输出测试集中的第一个元素&#xff08;输出img信息和target&#xff09; 查看分类classes 打断点–>右键Debug–>找到classes 代码 import torchvisiontrain_set torchvision.datasets.CIFAR10(root"./data…

数据结构|排序总结(1)|直接插入排序

排序分类 插入排序&#xff1a;直接插入排序&#xff0c;希尔排序 选择排序&#xff1a;选择排序&#xff0c;堆排序 交换排序&#xff1a;冒泡排序&#xff0c;快速排序 归并排序 插入排序 直接插入排序 相当于摸牌&#xff0c;例如我们现在手上有{2&#xff0c;4&#xff0…

基于单片机光伏太阳能跟踪系统设计

**单片机设计介绍&#xff0c;基于单片机光伏太阳能跟踪系统设计 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机光伏太阳能跟踪系统的设计&#xff0c;旨在通过单片机技术实现对光伏太阳能设备的自动跟踪&#xff0c;以提高太阳…

前后端开发之——文章分类管理

原文地址&#xff1a;前后端开发之——文章分类管理 - Pleasure的博客 下面是正文内容&#xff1a; 前言 上回书说到 文章管理系统之添加文章分类。就是通过点击“新建文章分类”按钮从而在服务端数据库中增加一个文章分类。 对于文章分类这个对象&#xff0c;增删改查属于配…

k8s 持久化存储解析:hostPath与NFS的应用与探索

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、k8s为什么要有持久化存储 2、NFS简介…

post请求搜索功能爬虫

<!--爬虫仅支持1.8版本的jdk--> <!-- 爬虫需要的依赖--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency>…