【数据结构与算法篇】二叉树链式结构及实现

【数据结构与算法篇】二叉树链式结构及实现

🥕个人主页:开敲🍉

🔥所属专栏:每日刷题🍍

🌼文章目录🌼

4. 二叉树链式结构的实现

    4.1 前置说明

    4.2 二叉树的遍历

        4.2.1 前序、中序以及后序遍历

        4.2.2 层序遍历

    4.3 结点个数及高度等

    4.4 二叉树基础OJ联系

    4.5 二叉树的创建和销毁

4. 二叉树链式结构的实现
    4.1 前置说明

  在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,为了降低大家学习成本,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等二叉树结构了解的差不多时,我们反过头再来研究二叉树真正的创建方式。

typedef int BTDataType;
typedef struct BinaryTreeNode
{
      BTDataType _data;
      struct BinaryTreeNode* _left;
      struct BinaryTreeNode* _right;
      }BTNode;


BTNode* CreatBinaryTree()
{
    BTNode* node1 = BuyNode(1);
    BTNode* node2 = BuyNode(2);
    BTNode* node3 = BuyNode(3);
    BTNode* node4 = BuyNode(4);
    BTNode* node5 = BuyNode(5);
    BTNode* node6 = BuyNode(6);
    node1->_left = node2;
    node1->_right = node4;
    node2->_left = node3;
    node4->_left = node5;
    node4->_right = node6;

    return node1;
}

注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式后序详解重点讲解。
再看二叉树基本操作前,再回顾下二叉树的概念,二叉树是:

从概念中可以看出,二叉树定义是递归式的,因此后序基本操作中基本都是按照该概念实现的。

    4.2 二叉树的遍历
        4.2.1 前序、中序以及后序遍历

  学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的结点进行相应的操作,并且每个结点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

  按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

  ① 前序:对于每个结点,都满足 根 一> 左子树 一> 右子树 的遍历顺序

  ② 中序:对于每个结点,都满足 左子树 一> 根 一> 右子树 的遍历顺序

  ③ 后序:对于每个结点,都满足 左子树 一> 右子树 一> 根 的遍历顺序

  由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

  前序遍历图形解释:

类似的可以推出中序遍历:

以及后序遍历:

        4.2.2 层序遍历

  层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根结点所在层数为1,层序遍历就是从所在二叉树的根结点出发,首先访问第一层的树根结点,然后从左到右访问第2层上的结点,接着是第三层的结点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

  

    4.3 结点个数及高度等

//二叉树结点个数

//求二叉树结点个数,也就是将每个根节点左右子树结点个数相加,再加上根结点自身。
int TreeNodeSize(BT* node)
{
    if (node == NULL)
    {
        return 0;
    }
    return 1 + TreeNodeSize(node->left) + TreeNodeSize(node->right);
}

//二叉树叶结点个数
int TreeLeafSize(BT* node)
{
    if (node == NULL)
    {
        return 0;
    }
    if (node->left == NULL && node->right == NULL)
    {
        return 1;
    }
    return TreeLeafSize(node->left) + TreeLeafSize(node->right);
}

//二叉树第K层结点个数
int TreeKSize(BT* node,int k)
{
    if (node == NULL)
    {
        return 0;
    }
    else if (k == 0)
    {
        return 1;
    }
    return TreeKSize(node->left,k-1) + TreeKSize(node->right,k-1);
}

//查找值为x的结点
BT* FindX(BT* node, BTDataType x)
{
    if (node == NULL)
    {
        return NULL;
    }
    if (node->val == x)
    {
        return node;
    }
    BT* ansleft = FindX(node->left, x);
    if (ansleft)
    {
        return ansleft;
    }
    return FindX(node->right,x);
}

    4.4 二叉树基础OJ联系

   965. 单值二叉树 - 力扣(LeetCode)

   100. 相同的树 - 力扣(LeetCode)

  101. 对称二叉树 - 力扣(LeetCode)

   144. 二叉树的前序遍历 - 力扣(LeetCode)

   94. 二叉树的中序遍历 - 力扣(LeetCode)

   145. 二叉树的后序遍历 - 力扣(LeetCode)

  572. 另一棵树的子树 - 力扣(LeetCode)

    4.5 二叉树的创建和销毁

  二叉树遍历_牛客题霸_牛客网 (nowcoder.com)

  //前序遍历创建二叉树
BT* BinaryTreeCreate(BTDataType* a, int* n)
{
    if (a[*n] == 0)
    {
        (*n)++;
        return NULL;
    }
    BT* node = (BT*)malloc(sizeof(BT));
    node->val = a[(*n)++];
    node->left = BinaryTreeCreate(a, n);
    node->right = BinaryTreeCreate(a, n);
    return node;
}

//二叉树销毁(后序遍历)
void ReleaseBinaryTree(BT* node)
{
    if (node == NULL)
    {
        return;
    }
    ReleaseBinaryTree(node->left);
    ReleaseBinaryTree(node->right);
    free(node);
}

//判断二叉树是否是完全二叉树
bool IsFullBinaryTree(BT* node)
{
        QE q;
    //初始化队列
    QueInit(&q);
    //入列,队列中的val存放指向结点的指针
    if (node)
        QuePush(&q, node);

    while (!QueEmpty(&q))
    {
        QDataType phead = QueGetHead(&q);
        QuePop(&q);
        if (phead == NULL)
        {
            break;
        }

        QuePush(&q, phead->left);
        QuePush(&q, phead->right);
    }
    while (!QueEmpty(&q))
    {
        QDataType phead = QueGetHead(&q);
        if (phead)
        {
            QueRelease(&q);
            return false;
        }
        QuePop(&q);
    }
    QueRelease(&q);
    return true;
}

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

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

相关文章

【大模型】Spring AI对接ChatGpt使用详解

目录 一、前言 二、spring ai介绍 2.1 什么是Spring AI 2.2 Spring AI 特点 2.3 Spring AI 为开发带来的便利 2.4 Spring AI应用领域 2.4.1 聊天模型 2.4.2 文本到图像模型 2.4.3 音频转文本 2.4.4 嵌入大模型使用 2.4.5 矢量数据库支持 2.4.6 用于数据工程ETL框架 …

云动态摘要 2024-05-24

给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]大模型知识引擎体验招募 腾讯云 2024-05-21 大模型知识引擎产品全新上线,为回馈新老客户,50万token免费送,开通服务即领取! 云服…

蓝桥杯杨辉三角

PREV-282 杨辉三角形【第十二届】【蓝桥杯省赛】【B组】 (二分查找 递推): 解析: 1.杨辉三角具有对称性: 2.杨辉三角具有一定规律 通过观察发现,第一次出现的地方一定在左部靠右的位置,所以从…

优化css样式的网站

一、按钮的css样式 https://neumorphism.io/#e0e0e0https://neumorphism.io/#e0e0e0 二、渐变样式 Fresh Background Gradients | WebGradients.com 💎Come to WebGradients.com for 180 beautiful linear gradients in CSS3, Photoshop and Sketch. This collect…

IT革命浪潮:技术革新如何改变我们的生活与工作

一、技术革新与行业应用 当前的IT行业正处于前所未有的技术革新阶段。其中,量子计算和虚拟现实是两项引人注目的技术。 量子计算:量子计算以其超越传统计算的潜力,正在逐步从理论走向实践。在材料科学、药物研发和气候模型等复杂计算领域&a…

JAVA中的代理:代理的作用+静态代理的实现+动态代理的实现

JAVA中的代理:代理的作用静态代理的实现动态代理的实现 一、代理的作用二、静态代理实现方式2.1 实现原理2.2 示例 三、动态代理 一、代理的作用 代理是一种设计模式 主要目的:提供了对目标对象另外的访问方式 代理的好处: 目标对象可以间…

前端开发攻略---用Vue实现无限滚动的几种方法

目录 1、原理 2、使用CSS动画 代码: 3、使用JS实现 代码: 1、原理 复制内容:将需要滚动的内容复制一次,并将这些副本放置在原始内容的后面。这样,当用户滚动到内容的末尾时,就会无缝地切换回到内容的起…

链表-设计LRU缓存结构

题目描述: 代码实现:这里记录了根据LRU算法原理最直接理解的代码实现。 import java.util.*;//存储输入内容,记录访问权值 class CounterInfo {int key;int value;int times;//代表key对应的权值,值越小优先级越高public Counter…

【学习笔记】Webpack5(Ⅱ)

Webpack 3、高级篇 3.1、提升开发体验 —— SourceMap 3.2、提升打包速度 3.2.1 HotModuleReplacement 3.2.2 OneOf 3.2.3 Include / Exclude 3.2.4 Cache 3.2.5 Thread 3.3、减少代码体积 …

Strategy设计模式

Strategy设计模式举例。 看图&#xff1a; 代码实现&#xff1a; #include <iostream>using namespace std;class FlyBehavior { public:virtual void fly() 0; };class QuackBehavior { public:virtual void quack() 0; };class FlyWithWings :public FlyBehavior …

轻量级 K8S 环境 安装minikube

文章目录 操作系统DockerDocker CE 镜像源站使用官方安装脚本自动安装 &#xff08;仅适用于公网环境&#xff09;安装校验Docker代理docker permission denied while trying to connect to the Docker daemon socket minikubekubectl工具minikube dashboard参考资料 操作系统 …

WORD、PPT技巧

WORD技巧 编辑设置 word标题导航窗口怎么调出word2016&#xff0c;缩小了页面&#xff0c;可是怎么是竖着的一页一页排列啊&#xff1f;以前不是好几页横排着的么&#xff1f;怎么设置&#xff0c;求救&#xff1a;在Word标题栏那一行找到“视图”&#xff0c;点击“显示比例…

刷题之路径总和Ⅲ(leetcode)

路径总和Ⅲ 这题和和《为K的数组》思路一致&#xff0c;也是用前缀表。 代码调试过&#xff0c;所以还加一部分用前序遍历数组和中序遍历数组构造二叉树的代码。 #include<vector> #include<unordered_map> #include<iostream> using namespace std; //Def…

HCIE是什么证书?为什么要考?

每当我发一些关于HCIE的话题时&#xff0c;总有小伙伴过来问“啥是HCIE啊&#xff1f;”今天就一起来了解下&#xff0c;到底什么是HCIE&#xff1f;为什么这么多人都要考HCIE? HCIE是华为认证ICT专家的缩写&#xff0c;它是华为认证体系中最高级别的ICT技术认证。HCIE全称为H…

JUnit5禁用测试用例

什么是禁用测试用例&#xff1a; 给用例添加禁用标识被禁用的用例执行后会添加跳过的状态可以禁用测试类、也可以禁用测试方法 使用场景&#xff1a; 在bug未解决之前&#xff0c;对应的测试用例则无需执行版本更新&#xff0c;某些用例暂时不可以 Disable注解&#xff1a;…

【Andoird开发】android获取蓝牙权限,搜索蓝牙设备MAC

<!-- Android 12以下才需要定位权限&#xff0c; Android 9以下官方建议申请ACCESS_COARSE_LOCATION --><uses-permission android:name"android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name"android.permission.ACCES…

可视化 | Seaborn中的矩阵图及示例

Seaborn是python提供的一个很棒的可视化库。它有几种类型的绘图&#xff0c;通过这些绘图&#xff0c;它提供了惊人的可视化能力。其中一些包括计数图&#xff0c;散点图&#xff0c;配对图&#xff0c;回归图&#xff0c;矩阵图等等。本文讨论了Seaborn中的矩阵图。 示例1&am…

微软密谋超级AI大模型!LangChain带你轻松玩转大模型开发

此前&#xff0c;据相关媒体报道&#xff0c;微软正在研发一款名为MAI-1的最新AI大模型&#xff0c;其参数规模或将达5000亿以上&#xff0c;远超此前微软推出的相关开源模型&#xff0c;其性能或能与谷歌的Gemini 1.5、Anthropic的Claude 3和OpenAI的GPT-4等知名大模型相匹敌。…

AI PC 的曙光:微软大胆出击与苹果竞争

AI PC 的曙光&#xff1a;微软大胆出击与苹果竞争 AI PC 的曙光&#xff1a;微软大胆出击与苹果竞争 概述 微软已正式进入 AI PC 时代&#xff0c;并且毫不避讳地直接向苹果的 MacBook 发起攻击。随着代号为“Copilot”的笔记本电脑的推出&#xff0c;微软准备彻底改变我们与…

vue 表格表头展示不下,显示。。。;鼠标悬浮展示全部

vue 表格表头展示不下&#xff0c;显示。。。&#xff1b;鼠标悬浮展示全部 <templateslot-scope"scope"slot"header"><span:title"临时证券类型"style"white-space:nowrap">{{ 临时证券类型 }}</span></templa…