数据结构——树与二叉树

news2024/9/30 19:27:39

目录

树与二叉树

1.树的定义

2.树的有关术语

3.二叉树(BinaryTree)

二叉树的性质:

特殊的二叉树

·满二叉树:

·完全二叉树

二叉树的存储结构 

顺序存储结构

链式存储结构

二叉树以及对应接口的实现

1.二叉树架构搭建

2.二叉树的创建

3.二叉树的销毁

4.二叉树的前中后序

5.求树的节点个数

6.求叶子结点个数(无左右孩子,度为0)

7.求树的深度

8.二叉树的层序遍历

顾名思义就是一层一层从左到右遍历

 拓展知识


树与二叉树

1.树的定义

树是n(n>=0)个结点构成的有限集合。

·当n=0时,称为空树

·树中有一个特殊的结点被称作“根(root)”,其余结点可以分为m个不相交的有限集,其中每一个   集合都是一颗树,被称为原来树的子树。(对于空树来说)

2.树的有关术语

(1)结点:树中独立的单元格,包含一个数据元素及若干指向子树的分支。

(2)结点的度:结点的子树个数

(3)树的度:树中最大的结点的度,上图树的度为3.

(4)叶子结点:树中度为0的节点,叶子是这一类结点的总称。上图中的E、F、G、D都是叶子节点。

(5)双亲结点:有子树的结点,是其子树的双亲结点。上图的A就是B、C、D的双亲结点

(6)子结点:上图B、C、D是A的子结点

(7)兄弟结点:上图B、C、D互为兄弟结点

(8)结点的层次:根结点在1层,其他结点的层次等于其父节点的层次+1

  (9)   树的深度:所有结点中最大的层次就是树的深度

(10)森林:m棵不相交的树的集合

3.二叉树(BinaryTree)

二叉树是特殊的树,该树每个结点的度<=2。

二叉树的性质:

1.二叉树在第k层上最多有2^(k-1)个结点

2.深度为k的二叉树最多有2^k-1个结点

3.一颗二叉树如果度为0的结点有N0个,度为2的结点有N2个,则N0=N2+1

特殊的二叉树

·满二叉树:

深度为k且一共有2^k-1个结点,第i层的节点树为2^(i-1)

·完全二叉树

深度为k,前k-1层每层都是满结点,最后退成结点从左向右连续排列

二叉树的存储结构 

顺序存储结构

用数组存储二叉树,按从上到下,从左到右顺序存储。(比较适合满二叉树和完全二叉树)

对于普通的二叉树,存储起来空元素的结点就会导致空间的浪费

链式存储结构

这里最常用的存储类型就是运用两指针

1.两指针分别是左右孩子

2.两指针分别是左孩子和右兄弟

二叉树以及对应接口的实现

1.二叉树架构搭建

typedef char BTDataType;//利于适用于多种类型的数据操作

typedef  struct BinaryTree

{

        BTDataType val;

        struct BinaryTree*left;

        struct BinaryTree*right;//左右孩子指针

}BTNode;

2.二叉树的创建

BTNode* BTbyNode(BTDataType x)

{

        BTNode*newnode=(BTNode*)malloc(sizeof(BTNode));

        if(newnode==NULL)

        {

                perror("malloc fail!!!");

                return NULL;

        }

        newnode->val=x;

        newnode->left=NULL;

        newnode->right=NULL;

        

        return newnode;

}

BTNode* CreateTree()
{
    BTNode* l1 = BTByNode(1);
    BTNode* l2 = BTByNode(2);
    BTNode* l3 = BTByNode(3);
    BTNode* l4 = BTByNode(4);
    BTNode* l5 = BTByNode(5);

    l1->left = l4;
    l1->right = l2;
    l2->left = l3;
    l4->right = l5;

    return l1;
}

3.二叉树的销毁

void TreeDestroy(BTNode*root)

{

        if(root==NULL)

                return ;

        TreeDestroy(root->left);

        TreeDestroy(root->right);

        free(root);

        //root==NULL//这里是局部变量,在函数内部置空没有用,要在调用销毁函数的下面置空root

4.二叉树的前中后序

关于二叉树非常重要的一个思想就是分治思想,将大问题转化成多个小问题去解决。换成二叉树也就是,将根节点问题不断转化给左右子树

void PrevOrder(BTNode*root)//前序----根---左---右

{

        if(root==NULL)

                return ;

        printf("%c  ",root->val);

        PrevOrder(root->left);

        PrevOrder(root->right);

 void InOrder(BTNode*root)//中序----左---根---右

{

        if(root==NULL)

                return ;

        InOrder(root->left);

        printf("%c  ",root->val);

        InOrder(root->right);

}

void PostOrder(BTNode*root)//后序----左---右---根

{

        if(root==NULL)

                return ;

        PostOrder(root->left);

        PostOrder(root->right);

        printf("%c  ",root->val);

5.求树的节点个数

int BinaryTreeSize(BTNode* root)

{

        return root==NULL?0:BinaryTreeSize(root->left)

                                        +BinaryTreeSize(root->right)+1;

6.求叶子结点个数(无左右孩子,度为0)

int BinaryTreeleafSize(BTNode* root)

{

        if(root==NULL)

                return 0;

        if(root->left==NULL&&root->right==NULL)

                return 1;

        return BinaryTreeleafSize(root->left)+BinaryTreeleafSize(root->right);

7.求树的深度

int BinaryTreeHeight(BTNode* root)

{

        if(root==NULL)

                return 0;

        int h1=BinaryTreeHeight(root->left);

        int h2=BinaryTreeHeight(root->right);

        return h1>h2?h1:h2;

8.二叉树的层序遍历

顾名思义就是一层一层从左到右遍历

用一个队列来实现当一个根节点出队列,就将它的左右结点入队列,直到队列中无元素

void TreeLevelOrder(BTNode* root)

{

        Queue q;//创建一个队列对象

        QueueInit(&q);//队列初始化

        if(root)

                QueuePush(&q,root);//将根结点指针入队列

        

        while(!QueueEmpty(&q))//判断队列是否为空,为空说明遍历结束

        {

                BTNode*front=QueueFront(&q);//取队首元素,防止下面出队首元素找不到根结点位置

                QueuePop(&q);//将队首元素出队列

                if(front)

                {

                        printf("%c ",front->val);

                        QueuePush(&q,front->left);

                        QueuePush(&q,front->right);//将左右孩子入队列

                 }

        }

        TreeDestroy(root);

        root==NULL;

 拓展知识

知道一个树的结点数量,怎么算出该树的可能有几种情况

我们定义f(n)表示结点数为n的二叉树的情况数

零个结点也是一种情况,所以f(0)=1;

一个结点时,只有一种情况,则f(1)=1;

两个结点时,有两种情况,根结点一个,剩下结点左右孩子各一种情况,则f(2)=f(1)+f(1)=2;

三个结点时,根节点一个节点,剩下结点分为三种情形:

1.左子树两个结点右子树零个

2.右子树两个结点左子树零个

3.左右子树各一个节点

则f(3)=f(2)*f(0)+f(1)*f(1)+f(0)*f(2)

经过推算得到f(n)=f(n-1)*f(0)+f(n-2)*f(1)+…+f(0)*f(n-1)

上述式子可以化简成(2n)! / ( n! (n+1)! )在数学中被称为卡特兰数

有了上述式子知道结点数就能轻松算出树可能存在的情况数

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

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

相关文章

docker将本地镜像pull到阿里云和registry

目录 一、上次到阿里云服务器 1、制作一个带有vim功能的Ubuntu镜像 2、在阿里云上面创建镜像仓库 3、从阿里云仓库中上传和拉取镜像 二、上传镜像到本地私有库registry 1、下载镜像docker registry 2、运行私有库registry&#xff0c;相当于本地有个私有docker hub。 3…

MUNIK第二届功能安全及自动驾驶研讨会将在沪召开

2024年4月26日,由上海秒尼科技术服务有限公司(以下简称“Munik”)联合Parosoft主办的“第二届功能安全及自动驾驶研讨会”将在上海虹桥隆重开幕。 据了解,本次功能与自动驾驶安全研讨会,将聚焦在ISO 26262标准体系下,自动驾驶新形势下各个零部件供应商如何满足功能安全等相关重…

Ubuntu Desktop 快速显示桌面

Ubuntu Desktop 快速显示桌面 1. 快捷方式2. show desktop iconReferences 1. 快捷方式 Ctrl Win D&#xff1a;快速显示桌面 / 恢复屏幕显示 2. show desktop icon System Settings -> Appearance -> Add show desktop icon to the launcher ​ 点击 Show Desktop…

Druid连接池的能力介绍与使用方法

Druid连接池的能力介绍与使用方法 本文将介绍druid连接池的能力&#xff1a;监控sql调用数据&#xff08;慢sql、调用量、异常堆栈&#xff09;、防止sql注入和数据库密码加密。 1. Druid连接池简介 Alibaba Druid官网使用手册里是这样介绍的&#xff1a;Druid连接池是阿里巴…

云原生网络魔术师:Docker高级网络实战演练与深度解析

在Docker的世界中&#xff0c;网络无疑是一块充满魔力的土地。当我们超越了基础的网络配置&#xff0c;步入Docker高级网络领域时&#xff0c;你会发现一个全新的、强大而灵活的网络模型正在等待你的探索。本文将带你亲历Docker高级网络实战操作&#xff0c;揭开overlay网络、自…

【动态规划】Leetcode 70. 爬楼梯

【动态规划】Leetcode 70. 爬楼梯 解法1 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 输入…

GaussDB WDR分析之集群报告篇

AWR报告目前已经成为Oracle DBA分析问题&#xff0c;定位故障最为重要的报告&#xff0c;阅读与分析AWR报告的技能也是Oracle DBA必备的技能。国产数据库为了提高运维便捷性&#xff0c;都在做类似Oracle AWR报告的模仿&#xff0c;只不过由于指标体系不够完善&#xff0c;因此…

Windows系统安装WampServer结合内网穿透实现公网访问本地服务

文章目录 前言1.WampServer下载安装2.WampServer启动3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 Wamp 是一个 Windows系统下的 Apache PHP Mysql 集成安装环境&#xff0c;是一组常用来…

网络安全笔记-day7,共享文件服务器

文件共享服务器 准备阶段 打开虚拟机win2003 创建文件 D:. —share   –down   |  test1.txt   |   —up     01xxx.txt     02xxx.txt 配置IP win2003 192.168.1.10 255.255.255.0 winxp 192.168.1.20 255.255.255.0 创建共享文件夹 创建共享&#xff1…

Axure RP 9 for Mac中文激活版:原型设计工具

Axure RP 9 for Mac是一款值得设计师信赖的原型设计工具。它以其卓越的性能和稳定的运行赢得了广大用户的赞誉。 软件下载&#xff1a;Axure RP 9 for Mac中文激活版下载 在Axure RP 9中&#xff0c;您可以尽情发挥自己的设计才华&#xff0c;创造出独一无二的原型作品。无论是…

【MySQL】9. 内置函数

函数 1. 日期函数 获得年月日&#xff1a; mysql> select current_date(); ---------------- | current_date() | ---------------- | 2024-03-23 | ---------------- 1 row in set (0.00 sec)获得时分秒&#xff1a; mysql> select current_time(); ------------…

看完就等于拿捏浮点数在内存中的储存了

诸君又该学习了&#xff0c;今天我们继续来一睹浮点数的奥妙真容。 经过前面文章对整形提升相关的解释&#xff0c;我们都对整形和字符在内存空间上的储存已经有了大概的认知&#xff0c;那么现在我们就来好好讲讲浮点数在内存中的储存规则。 目录 浮点数与整形储存的不同 …

which is not functionally dependent on columns in GROUP BY clause 错误解决方法

今天遇到了which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_modeonly_full_group_by的错误&#xff0c;记录一下解决方法。 该错误是因为在SQL语句中用到了聚合函数&#xff0c;但是聚合函数之外的字段没有全部放到group …

电脑电池健康度查询

首先使用winr 输入cmd&#xff0c;打开黑窗口 再出入以下代码&#xff1a; powercfg/batteryreport将路径中文件找到即可查看电池健康度。

软件测试(自动化测试)

1. Selenium 1.1 Selenium是什么&#xff1f; 用来做web自动化测试的框架。 1.2 Selenium特点 支持各种浏览器&#xff0c;支持各种平台&#xff0c;支持各种语言&#xff0c;有丰富的API&#xff0c; 1.3 工作原理 1.4 Selenium环境搭建 下载配套浏览器及驱动 这里使用Ch…

vcs编译选项--不常用

1&#xff09;如何查看波形的毛刺&#xff08;glitch&#xff09; 参考&#xff1a;公众号&#xff1a;IC学社 需要添加仿真选项&#xff1a;fsdbglitch0 “值得说明的是&#xff0c;glitch 对 design 是非常不好的&#xff0c;需要规避&#xff0c;设计代码中应该具有检查 g…

Express:快速搭建Node.js应用的基石

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

DataV 在HTML中使用

一&#xff1a;什么是DataV 介绍 | DataV (jiaminghi.com) 组件库基于Vue &#xff08;React版 (opens new window)&#xff09; &#xff0c;主要用于构建大屏&#xff08;全屏&#xff09;数据展示页面即数据可视化&#xff0c;具有多种类型组件可供使用&#xff1a;…

[leetcode] 138. 随机链表的复制

给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节点的 n…

Spring Bean加载优先级

当我们使用 ConditionalOnMissingBean / ConditionalOnBean注解去给某个 bean 注入赋予条件时&#xff0c;那在条件判断时我们需要确保条件判断过程所需的环境已准备好。 举个例子 下面的代码中有两个配置类&#xff0c;涉及两个 Bean 的注入 配置类 ConfigA 需要注入一个 A…