数据结构:二叉树(2)

ps:爆更第二期


前言

普通的树的实用价值比较小,将树更一步特殊化成二叉树,将获得更多的特殊性质。
例如搜索二叉树,红黑树等。
这篇博文主要介绍二叉树的基础知识,进阶版高级二叉树,后续会持续更新。

二叉树的概念

一棵二叉树是结点的一个有限集合,
该集合:

  1. 或者为空
  2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成

老规矩,上图
在这里插入图片描述
在上一篇博客中,介绍了度的概念,
二叉树救赎一颗树,如果他的度不超过2,那他就是一颗二叉树。

二叉树的几种情况
在这里插入图片描述


我们怎么去认识一颗二叉树呢?

对于任意一颗二叉树,我们都要将其这么看:
根,左子树,右子树
左子树也要看成根,左子树,右子树

为什么这么说呢?读下去,你就懂啦

特殊的二叉树

(1)满二叉树
一棵二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是
说,如果一个二叉树的层数为K,且结点总数是 ,则它就是满二叉树。

也就是说,满二叉树的每一层都要是满的。

(2)完全二叉树
完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K
的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对
应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。(堆就是一颗完全二叉树)

也就是说,完全二叉树除了最后一层,其他层都必须是满的,而且,就算最后一层没满,也需要从左到右连续。

在这里插入图片描述

二叉树的性质

1.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有 2i-1 个结点.
2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2n -1 .
3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为 n2,则有 n0 = n2 +1
4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度h= log(N+1). (ps: 是log以2为底,n+1为对数)
5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

  1. 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
  2. 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
  3. 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

这些都比较好理解,比较难理解的是第三点

对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为 n2,则有 n0 = n2 +1

为什么这么说呢?
最初的二叉树假设只有根节点,此时
n0 = 1, n2 = 0
在后续添加节点的过程中,只会出现两种情况

  1. n0 + 1, n2 + 1
  2. n0 不变,n2不变

读者可以尝试画图证明一下。

二叉树的存储

二叉树的存储分为两种情况

  1. 顺序存储
    适合用于完全二叉树,其中堆就是采用顺序存储实现。
    传送门:数据结构:堆

  2. 链式存储
    对于普通的二叉树,使用链式存储是最佳的方式。
    因为二叉树最多只有两个子节点,所以不用使用左孩子右兄弟表示法,直接用两个指针分别表示左孩子和右孩子即可。

struct Node
{Node* leftchild;Node* rightchild;DataType val;
};

二叉树的遍历

二叉树比较复杂,和之前的线性表遍历不太相同。
二叉树的遍历分为前序遍历,中序遍历,后续遍历,以及层序遍历。

前序遍历:根,左孩子,右孩子
中序遍历:左孩子,根,右孩子
后续遍历:左孩子,右孩子,根

前中后序遍历


作者感觉在这个地方没有讲清楚,十分抱歉


前中后序遍历的实现基于分治思想,使用递归实现(也可用非递归)
这里就到了前面说要把一棵树看成根,左子树,右子树的时候了。

以前序遍历为例,三种顺序遍历类似。
先分治成小问题:遍历根,左子树,右子树。
递归还需要结束条件,也就是最小子问题。
这里的子问题是遇到空树,千万不要想成遇到叶子结点

void prevOrder(TreeNode* root)
{if(root == nullptr)return;cout << root->val << endl;//根节点prevOrder(root->leftchild);//左子树prevOrder(root->rightchild);//右子树
}

在这里插入图片描述
利用这张图,可以帮助理解一下前序遍历的递归过程。

中序遍历与后序遍历类似,这里就不详细讲解了。


层序遍历

层序遍历的思路非常的巧妙
层序遍历利用队列实现

首先,将根节点进入队列,
每次将队首元素出队列,队首元素的左右非空子节点入队列
直到队列为空,则层序遍历完毕。

void LevelOrder(TreeNode* root)
{ if(root == nullptr)return;queue<TreeNode*> q;
q.push(root);while(!q.empty())
{TreeNode* front = q.front();q.pop();cout << front->val;if(front->leftchild)q,push(front->childleft);if(front->rightchild)q.push(front->rightchild);
}}

在这里插入图片描述


二叉树的节点个数及高度等

依旧是采用分治思想,分解成子问题,用递归的方式来解决问题。

  1. 二叉树节点个树
    其实就是左子树节点个数 + 右子树节点个数 + 1
  2. 二叉树的高度
    其实就是左右子树高度的最大值 + 1
  3. 二叉树叶子结点的个数
    其实就是左子树叶子结点个数 + 右子树叶子结点个数
  4. 二叉树中查找val = k的节点
    其实就是根节点查找,左子树查找,右子树查找
size_t size(Node* root)
{if (root == nullptr)return 0;return size(root->leftchild) + size(root->rightchild) + 1;
}size_t height(Node* root)
{if (root == nullptr)return 0;return max(height(root->leftchild), height(root->rightchild)) + 1;
}size_t size_leaf(Node* root)
{if (root == nullptr)return 0;if (root->leftchild == nullptr && root->rightchild == nullptr)return 1;return size_leaf(root->leftchild) + size_leaf(root->rightchild);
}Node* find(Node* root, DataType val)
{if (root == nullptr)return nullptr;if (root->val == val)return root;Node* left = find(root->leftchild, val);if (left)return left;return find(root->rightchild, val);
}

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

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

相关文章

RK3568平台(基础篇)万用表的使用

一.万用表的通断判断 万用表两个笔头的插法:黑笔头是插在COM的孔里面,红色笔头可以插在其他的三个孔里面,20A和mA分别用来测电流,另外一个孔可以用来测其他(电压 电阻)。 以下这个三角符号(像wifi一样的)可以用来测通断: 使用万用表的红笔和黑笔进行短接,这时候两端…

PAT (Advanced Level) Practice——1020Tree Traversals

链接&#xff1a; 1020 Tree Traversals - PAT (Advanced Level) Practice (pintia.cn) 题目大意&#xff1a; 首先给出一个整数n&#xff0c;表示序列一共有多少个数。接下来给出一棵树的后序遍历和中序遍历&#xff0c;根据后序遍历和中序遍历给出层序遍历。 题解&#x…

【技术调研】三维(7)-Unity基础笔记

安装 ​ 最好使用长期维护版本。 创建项目 ​ 略 窗口布局 Hierarchy:层级面板,展示当前打开的场景里面有哪些物体。 Scene:场景面板,显示当前场景的样子 Game:游戏面板,场景运行的时候的样子 Inspector:检视面板(或属性面板),查看一个游戏物体由哪些组件组成。 …

德勤校招网申笔试综合能力测试SHL题库与面试真题攻略

德勤的综合能力测试&#xff08;General Ability&#xff09;是其校园招聘在线测评的关键环节&#xff0c;旨在评估应聘者的多项认知能力。以下是对这部分内容的全面整合&#xff1a; 综合能力测试&#xff08;General Ability&#xff09; 测试时长为46分钟&#xff0c;包含…

9.3Otsu阈值分割

基本概念 在OpenCV中&#xff0c;Otsu阈值分割是一种全局阈值分割方法&#xff0c;但它会自动选择一个最佳的阈值来分割图像&#xff0c;这个阈值是通过最小化类内方差或等价地最大化类间方差来确定的。OpenCV提供了cv::threshold函数来实现这一功能&#xff0c;其中可以指定c…

线段树-认识线段树+实现线段树

一、认识线段树 1、定义 线段树是平衡二叉树 2、特点 线段树将一个区间划分成单元区间&#xff0c;每个单元区间对应线段树中的一个结点 3、应用 频繁查找一个数组中指定区间内的和、最值 学了动态规划后使用迭代要好过使用递归&#xff0c;因为递归每次进去是有空间损耗…

如何在qtcreator debugger上运行gdb命令

How to run gdb commands from qtcreator debugger? | Qt Forum gdb 调试基础操作和在qtcreator中使用gdb调试_qt gdb-CSDN博客 输出变量名&#xff1a; p变量名 ------------ gdb调试技巧&#xff08;二&#xff09;———— gdb 条件断点_gdb设置带函数入参判断的条件断点…

UE Asset Batch Duplication插件

目录 准备工作 "Scripting library" 三个最重要的功能&#xff08;前两个是UEditorUtilityLibrary中的&#xff09; 自动创建声明&#xff1a; TArray T 的含义 F 的含义 Live Coding &#xff08;Ctrlalt F11&#xff09; Live Coding 的工作流程&#xff…

时序预测|基于灰狼优化LightGBM的时间序列预测Matlab程序GWO-LightGBM 单变量和多变量 含基础模型

时序预测|基于灰狼优化LightGBM的时间序列预测Matlab程序GWO-LightGBM 单变量和多变量 含基础模型 文章目录 一、基本原理原理概述流程注意事项 二、实验结果三、核心代码四、代码获取五、总结 一、基本原理 时序预测中使用灰狼优化&#xff08;GWO&#xff09;结合LightGBM的…

Hash-通过哈希桶解决Hash冲突

哈希桶 基本结构 template<class T> struct HashNode {T _data;HashNode<T>* _next; }; template<class K,class T,class KeyOfT> class HashTable {typedef HashNode<T> Node; public:private:vector<Node*> _tables;size_t _num; }; insert …

《飞机大战游戏》实训项目(Java GUI实现)(设计模式)(简易)

目录 一、最终实现后&#xff0c;效果如下。 &#xff08;1&#xff09;简单介绍本游戏项目&#xff08;待完善&#xff09; &#xff08;2&#xff09;运行效果图&#xff08;具体大家自己可以试&#xff09; 初始运行情况。 手动更换背景图。 通过子弹攻击敌机&#xff0c;累…

java之单链表的基本概念及创建

1.链表的概念: 链表是一种 物理存储结构上非连续 存储结构&#xff0c;数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。 组成结构: 由一系列节点组成&#xff0c;每个节点包含数据域和指向下一个节点的指针。 优点: 动态大小&#xff0c;易于插入和删除操作。 缺点…

无人机集群路径规划:​北方苍鹰优化算法(Northern Goshawk Optimization,NGO)​求解无人机集群路径规划,提供MATLAB代码

一、单个无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径&#xff0c;使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一&#xff0c;它可以通过算法和模型来确定无人机的航迹&#xff0c;以避开障碍物、优化…

51单片机——LED灯篇

一、LED与单片机P2管脚相连 二、点亮一个LED灯 #include <STC89C5xRC.H> void main() { P2 0xFE; //1111 1110 } P2有8个管脚&#xff0c;对应8个二进制位。 LED灯右侧接电源是正极&#xff08;1&#xff09;&#xff0c;左侧给负极&#xff08;0&#xff09;即可…

Web_php_include 攻防世界

<?php show_source(__FILE__); echo $_GET[hello]; $page$_GET[page]; while (strstr($page, "php://")) { 以是否检测到php://为判断执行循环$pagestr_replace("php://", "", $page);//传入空值&#xff0c;替换 } include($page); ?&g…

第四范式发布AIGS Builder企业级软件重构助手,以生成式AI重构企业软件

产品上新 Product Release 今天&#xff0c;第四范式发布企业级软件重构助手——AIGS Builder&#xff0c;可快速重构软件交互体验。传统的企业软件开发&#xff0c;每次迭代通常要以月计。基于第四范式AIGS Builder大模型&#xff0c;用生成式Agent替代复杂的界面&#xff0c;…

AI绘制调整虚线教程

1、打开ai的软件&#xff0c;执行菜单栏中的文件—新建&#xff0c;新建一个大小任意的画板&#xff0c;画板大小根据自己的需要来设置。 2、选择工具箱中的直线段工具&#xff0c;将填充设置为无&#xff0c;描边设置为黑色&#xff0c;描边大小稍微设置大一点&#xff0c;画一…

模拟实现STL的stack、queue、deque等的介绍

文章目录 前言一、模拟实现stack二、模拟实现queue三、 deque总结 前言 模拟实现STL的stack、queue、deque等的介绍 一、模拟实现stack STL的stack是通过增加一个容器的模板参数&#xff0c;不直接实现栈&#xff0c;让容器存储数据&#xff0c;并调用容器的接口实现栈 name…

环形链表问题——力扣141,142

环形链表问题——力扣141&#xff0c;142 141.判断链表是否带环142.给定一个链表&#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 NULL 141.判断链表是否带环 这道题不能用比较链表中的值来判断是否带环&#xff0c;因为链表中不同节点的值可以相同…

Java免税购物商城:Spring Boot技术实现

第二章 系统开发关键技术 2.1 JAVA技术 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterrise JavaBeans&#xff09;的全面支持&#xff0c;java servlet AI&#xff0c;JS&#xff08;java server ages&#xff09…