基础数据结构——二叉树

news2025/1/16 11:02:48

目录

一、二叉树性质

1、满二叉树、完全二叉树

2、平衡二叉树

3、不平衡二叉树

二、二叉树的存储

1、普通做法

2、竞赛做法

三、二叉树的遍历

1、宽度优先遍历

2、深度优先遍历

(1)先(根)序遍历

(2)中(根)序遍历

(3)中(根)序遍历的特点(⭐)

(4)后(根)序遍历

(5)三种遍历的关系

3、例题1——完全二叉树的权值(2019年省赛,lanqiaoOJ题号183)

4、例题2——FBI树(lanqiaoOJ题号571)

(1)普通做法

(2)竞赛做法


一、二叉树性质

  • 每个结点最多有两个子节点:左孩子、右孩子。以它们为根的子树称为左子树、右子树。
  • 二叉树的第 i 层,最多有 2^i-1 个节点。
  • 二叉树的每个节点不必全有左、右孩子,可以只有一个孩子或没有孩子,没有孩子的结点称为叶子节点。

1、满二叉树、完全二叉树

【满二叉树】

如果每一层的结点数都是满的,称为满二叉树。

【完全二叉树】

如果满二叉树只在最后一层有缺失,并且缺失的编号都在最后,那么称为完全二叉树。

几乎完美的平衡二叉树。

2、平衡二叉树

  • 在平衡二叉树上能进行极高效率的访问。例如满二叉树或完全二叉树,二叉树每一层的结点数量按 2 的倍数递增,能极快地扩展到很大的范围。
  • 一棵有 N 个结点的满二叉树,树的高度是 O(logN)。从根结点到叶子结点,只需要走 logN 步,例如 N =100万,树的高度仅有 20,只需要 20 步就能到达 100 万个结点中的任意一个。
  • 高级数据结构 ≈ 基于二叉树的数据结构(666)

3、不平衡二叉树

  • “链状” 二叉树。
  • 每一层都缺失很多结点,退化成一个长链条状。
  • 失去了二叉树天然的优势。
  • 只有在平衡的二叉树上才能进行高效的操作。
  • 不平衡的二叉树退化成了线性结构,和低效的链表没多大区别。

二、二叉树的存储

1、普通做法

class node:
    def __init__(self,s,l=None,r=None):
        self.val=None  #节点的值
        self.l=l       #指向左右孩子的存储位置
        self.r=r

2、竞赛做法

  • 为了编码简单,加快速度,一般用静态数组来实现二叉树。
  • 定义一个大小为 N 的静态结构体数组,用它存一棵二叉树。
  • 定义静态数:tree=['']*10000
  • 根节点:tree[1]
  • 节点 tree[p] 的左子节点:tree[2*p]
  • 节点 tree[p] 的右子节点:tree[2*p+1]

三、二叉树的遍历

1、宽度优先遍历

宽度优先遍历:一层层地遍历二叉树,用队列实现。

出队列的顺序是:EBGADFICH。按层次深度逐层输出。

2、深度优先遍历

  • 先 (根) 序遍历
  • 中 (根) 序遍历
  • 后 (根) 序遍历

(1)先(根)序遍历

def postorder(p):
    print(tree[p],end='')
    if tree[2*p]!='':
        postorder(2*p)
    if tree[2*p+1]!='':
        postorder(2*p+1)
  • 按父、左儿子、右儿子的顺序访问:
  • EBADCGFIH
  • 先序遍历的第一个结点是根 

(2)中(根)序遍历

def postorder(p):
    if tree[2*p]!='':
        postorder(2*p)
    print(tree[p],end='')
  • 按左儿子、父、右儿子的顺序访问:
  • ABCDEFGHI
  • 结果为什么是字典序?

(3)中(根)序遍历的特点(⭐)

  • ABCDEFGHI
  • 返回的结果:根结点左边的点都在左子树上,右边的都在右子树上。
  • 例如:E是根, E左边的 “ABCD” 在它的左子树上;
  • 例如:在子树 “ABCD” 上,B 是子树的根,那么“A”在它的左子树上, “CD”在它的右子树上。

(4)后(根)序遍历

def postorder(p):
    if tree[2*p]!='':
        postorder(2*p)
    if tree[2*p+1]!='':
        postorder(2*p+1)
    print(tree[p],end='')
  • 按左儿子、右儿子、父的顺序访问
  • ACDBFHIGE
  • 后序遍历的最后一个结点是根

(5)三种遍历的关系

  • 已知二叉树的:“中序遍历+先序遍历”,或者 “中序遍历+后序遍历”,都能确定一棵树。
  • 但是只有“先序遍历+后序遍历”,不能确定一棵树。例如左图,它们的先序遍历都是"1 2 3",后序遍历都是"3 2 1"。

3、例题1——完全二叉树的权值(2019年省赛,lanqiaoOJ题号183)

【题目描述】

给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A1, A2, …, AN。现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的结点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。注:根的深度是1。

【输入描述】

第一行包含一个整数 N (1<=N<=10^5) 。第二行包含 N 个整数 A1,  A2, ... , AN (-10^5 <= Ai <=10^5)

【输出描述】

一个整数表示答案。

【输入样例】

7

1 6 5 4 3 2 1

【输出样例】

2

p=[]
for i in range(0,33):   # 32层
    p.append(2**i)      # 每层的个数:p[]=1,2,4,8,16,...

n=int(input())
a=input().split(" ")
sum=[0]*32              # 记录每层的和

for i in range(0,n):
    for j in range(0,len(p)):
        if i+1>=p[j] and i+1<=p[j+1]:   # 计算每层的和
            sum[j]+=int(a[i])

maxx,mindeep=-1,-1
for i in range(0,len(sum)):
    if maxx<sum[i]:
        maxx,mindeep=sum[i],i
print(mindeep+1)
  • 一棵完全二叉树
  • 第一层1个,第2层2个,第3层4个,... ,
  • 最后第 k 层最多 2^(k-1) 个
  • 第 i 层存储第 2^(i-1) 个到第 (2^i)-1 个数。

4、例题2——FBI树(lanqiaoOJ题号571)

【题目描述】

我们可以把由 “0” 和 “1” 组成的字符串分为三类:全 “0” 串称为 B 串,全 “1” 串称为 I 串,既含 “0” 又含 “1” 的串则称为 F 串。FBI树是一种二叉树,它的结点类型也包括 F 结点,B 结点和 I 结点三种。由一个长度为 2^N 的 “01” 串 S 可以构造出一棵 FBI 树 T,递归的构造方法如下:

1. T 的根结点为 R,其类型与串 S 的类型相同;

2. 若串 S 的长度大于 1,将串 S 从中间分开,分为等长的左右子串 S1 和 S2;由左子串 S1 构造 R 的左子树 T1,由右子串 S2 构造 R 的右子树 T2。

现在给定一个长度为 2^N 的 “01” 串,请用上述构造方法构造出一棵 FBI 树,并输出它的后序遍历序列。

【输入描述】

第一行是一个整数 N (0<=N<=10)。第二行是一个长度为 2^N 的 “01” 串。

【输出描述】

输出一个字符串,即 FBI 树的后序遍历序列。

【输入样例】

3

10001011

【输出样例】

IBFBBBFIBFIIIFF

  • 用满二叉树来存题目的 FBI 树,满二叉树用静态数组实现。题目 N = 10 时,串的长度是 2N = 1024 ,有 1024 个元素,需要建一棵大小为 4096 的二叉树 tree[4096]。
  • 题目要求建一棵满二叉树,从左到右的叶子结点就是给定的串 S,并且把叶子结点按规则赋值为字符F、B、I,它们上层的父结点上也按规则赋值为字符F、B、I。
  • 最后用后序遍历打印二叉树。
  • 下面演示两种做法:普通做法、竞赛做法

(1)普通做法

节点用数据结构表示,用 l、r 分别指向左右子节点

class node:
    def __init__(self,s,l=None,r=None):
        self.val=None
        self.l=l
        self.r=r
        if '0' in s and '1' in s:
            self.val='F'
        elif '0' in s:
            self.val='B'
        else:
            self.val='I'

def bulid(s):
    if len(s)==1:
        return node(s)
    if len(s)==0:
        return None
    root=node(s,bulid(s[:len(s)>>1]),bulid(s[len(s)>>1:]))
    return root

def postorder(root):
    if root:
        postorder(root.l)
        postorder(root.r)
        print(root.val,end='')
    else:
        return

n=int(input())
s=list(input())
root=bulid(s)
postorder(root)

(2)竞赛做法

用一维数组存二叉树

def bulid_FBI(p,left,right):
    if left==right:
        if s[right]=='1':
            tree[p]='I'
        else:
            tree[p]='B'
        return
    mid=(left+right)//2
    bulid_FBI(2*p,left,mid)
    bulid_FBI(2*p+1,mid+1,right)
    if tree[2*p]=='B' and tree[2*p+1]=='B':
        tree[p]='B'
    elif tree[2*p]=='I' and tree[2*p+1]=='I':
        tree[p]='I'
    else:
        tree[p]='F'

def postorder(p):
    if tree[2*p]!='':
        postorder(2*p)
    if tree[2*p+1]!='':
        postorder(2*p+1)
    print(tree[p],end='')

n=int(input())
s=input()
tree=['']*4400
bulid_FBI(1,0,len(s)-1)
postorder(1)
        

以上,基础数据结构——二叉树

祝好

 

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

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

相关文章

【java中的集合框架】学习接触java中的集合,走上学习数据结构道路

前言&#xff1a; 大家好&#xff0c;我是良辰呀&#x1f3eb;&#x1f3eb;&#x1f3eb;&#xff0c;从今天开始&#xff0c;我们一起来探索数据结构的知识海洋。期待与大家结伴同行&#xff0c;gogogo。&#x1f36c;&#x1f36c;&#x1f36c; &#x1f9d1;个人主页&…

【自学C++】C++命名空间

C命名空间 C命名空间教程 C 中的命名空间实际上就是一个由程序设计者命名的内存区域&#xff0c;程序设计者可以根据需要指定一些有名字的空间域&#xff0c;把一些全局实体分别放在各个命名空间中&#xff0c;从而与其他全局实体分隔开来。 命名空间是 ANSI C 引入的可以由…

前端入门笔记 03 —— Web(html CSS)布局

常用布局 包含两个定义&#xff1a; 尺寸 定位 定义通过CSS拾取网页元素&#xff0c;控制他们控制普通文档流&#xff0c;周边元素&#xff0c;父容器&#xff0c;浏览器窗口 覆盖默认布局行为盒子模型普通文档流 &#xff08;左到右&#xff0c;上到下&#xff09; 块级元素…

2022年中国数字化十大转型趋势

推动数字化发展既是数字时代构筑竞争新优势的战略选择&#xff0c;也是加快构建“双循环”新发展格局和打造高质量发展新引擎的现实需要。我国高度重视数字化发展&#xff0c;不断完善政策措施&#xff0c;着力推动数字化转型。从行业发展看&#xff0c;构建以数据为驱动、以客…

Redis(一)

Nosql 即 Not-Only SQL&#xff08; 泛指非关系型的数据库&#xff09;&#xff0c;作为关系型数据库的补充。 Nosql 作用&#xff1a;应对基于海量用户和海量数据前提下的数据处理问题。 特征 降低磁盘IO次数&#xff0c;越低越好 —— 内存存储 去除数据间关系&#xff…

网络技术基础

theme: qklhk-chocolate 网络技术基础 一、IP地址基础 IP地址是指在网络中用于标识发送或接收数据报文设备的唯一的逻辑地址。 IP地址的主要作用&#xff1a; 标识主机或网络设备&#xff08;标识其网络接口&#xff0c;提供其在网络中的位置&#xff09;网络寻址 •在IP网…

安装pytorch搭配cuda使用

问题 深度学习程序&#xff0c;在服务器运行&#xff0c;需要借助GPU加速。为了检测是否开启了GPU加速&#xff0c;采用以下代码&#xff1a; ~python >> import torch >> torch.cuda.is_available() >> false #说明没有使用GPU加速安装过程 安装老版本的…

如何做好美颜sdk与直播平台的适配?

美颜sdk作为目前社交视频拍摄平台用户的刚需&#xff0c;在近几年可谓是名声大噪&#xff0c;无论是强大的美颜功能还是多元化的趣味拍摄方案都让用户们“爱不释手”&#xff0c;平台自然也是看中了这一点&#xff0c;纷纷为自己平台接入美颜工具。但是&#xff0c;美颜sdk作为…

免费视频格式转换软件,6大免费视频转换器推荐

看到大多数人拥有电脑、智能电视&#xff0c;尤其是移动设备&#xff0c;这一代人并不奇怪。在线观看电影和视频是最常见的消磨时间的娱乐方式之一。能够通过网络观看视频是件好事。有些人还喜欢下载它以供离线观看&#xff0c;因为您并非一直都在使用 Wi-Fi。有时&#xff0c;…

C++——异常

文章目录1.C语言传统的处理错误的方式2. C异常概念3. 异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3异常安全3.4 异常规范4.自定义异常体系5.C标准库的异常体系6.异常的优缺点6.1 C异常的优点&#xff1a;6.2 C异常的缺点&#xff1a;1.C语言传统的处理错误的方式 传统…

Codeforces Round #842 (Div. 2)(A~D)

A. Greatest Convex给出数字k&#xff0c;输出最大的x&#xff0c;使得x满足大于等于1小于k&#xff0c;且x! (x - 1)!是k的倍数。思路&#xff1a;提取公因式得到&#xff0c;(x 1) * (x - 1)!&#xff0c;由题意知&#xff0c;x 1可以是k&#xff0c;故x最大是k - 1且一定…

如何制作网站?不知道这个诀窍你的网站等于白做

如何制作网站?不知道这个诀窍你的网站等于白做!#外贸 #独立站 #跨境电商 #网站优化 #网站建设 做每一个网页之前&#xff0c;先确定好网页里面的元素&#xff0c;你知道客户是谁&#xff0c;他目前生意做什么体量&#xff0c;主要做什么市场&#xff1f; 我在根据我拿到的这…

【实操篇】Linux的磁盘分区和挂载

目录 ●磁盘分区及挂载 ●典型案例实战 ●磁盘查询 1.查询系统整体磁盘使用情况 2.查询指定目录的磁盘占用情况 3.实用指令及其案例 ●树状目录展示 ●磁盘分区及挂载 简要介绍&#xff1a; 1.Linux无论有几个分区&#xff0c;还是分给哪个目录去使用。它归根结底也就只有…

C. Least Prefix Sum(优先队列)

传送门题意&#xff1a;给你一个长度为n的数组&#xff0c;你可以进行任意次操作&#xff08;也可能是0&#xff09;&#xff0c;可以使&#xff0c;然后给你一个数m&#xff0c;问你要进行多少次操作&#xff0c;才能使长度为m的前缀和的值在所有的前缀和中最小。思路&#xf…

JS 的 9 种作用域,你能说出几种?

作用域想必大家都知道&#xff0c;就是变量生效的范围&#xff0c;比如函数就会生成一个作用域&#xff0c;声明的变量只在函数内生效。 而这样的作用域一共有 9 种&#xff0c;其中几种绝大多数前端都说不出来。 下面我们就一起过一遍这 9 种作用域吧&#xff0c;看看你知道…

具有自主、多鳍和仿生机器人的鱼类三维游泳(2021)

具有自主、多鳍和仿生机器人的鱼类三维游泳(2021) 原文链接&#xff1a;https://iopscience.iop.org/article/10.1088/1748-3190/abd013 这是一篇仿生机器鱼的设计&#xff0c;该论文从鱼的仿生结构到具体的一部分电路设计都有非常详细的介绍&#xff0c;鱼的尺寸大小仅有手掌…

只有从根本上改变对于元宇宙的看法,才能将它的发展带入到一个全新阶段

经历了资本的狂热追捧之后&#xff0c;元宇宙开始进入到相对冷静的发展阶段里。在这样一个阶段&#xff0c;元宇宙不再被看成是一个万能的存在&#xff0c;不再被看成是一个无所不包的存在&#xff0c;而是变成了一个相对较为客观和理性的存在。看看Meta的表现&#xff0c;看看…

未处理的非法访问读异常(插入影像图代码)

本文迁移自本人网易博客&#xff0c;写于2013年1月5日&#xff0c;未处理的非法访问读异常&#xff08;插入影像图代码&#xff09; - lysygyy的日志 - 网易博客 (163.com)Acad::ErrorStatus CustomApplication::createAcDbRasterImageDef (AcDbObjectId & parObjectId, AC…

2023年入职/转行网络安全行业,该如何规划学习?

前言 前段时间&#xff0c;知名机构麦可思研究院发布了**《2022年中国本科生就业报告》**&#xff0c;其中详细列出近五年的本科绿牌专业&#xff0c;其中&#xff0c;信息安全位列第一。 网络安全前景 对于网络安全的发展与就业前景&#xff0c;想必无需我多言&#xff0c;作…

【Leetcode】699. 掉落的方块(困难)

一、题目 1、题目描述 在二维平面上的 x 轴上&#xff0c;放置着一些方块。 给你一个二维整数数组 positions &#xff0c;其中 positions[i][lefti,sideLengthi]positions[i] [left_i, sideLength_i]positions[i][lefti​,sideLengthi​] 表示&#xff1a;第 i 个方块边长…