数据结构----树

news2024/9/25 19:24:01

树的概念

1.树的定义:树是n(n>=0)个结点的有限集合

当n==0时,称为”空树“

当n>=0时,有且仅有一个称为”根“的特定结点,该结点没有前驱,但是却有一个或者多个后继结点。

除了根节点以外的n-1个结点可划分为多个有限集Ti(i = 1,2,3,4.....),每个Ti都是一个树,称为”根的子树“,每颗子树只有一个前驱结点,有一个或者多个后继结点。

树的基本术语

1.结点:包含一个数据元素以及若干指向其子树的分支。

结点的度:结点拥有子树的个数        树的度:树中所有结点的度的最大值。

叶子结点:度为0的结点                    内部结点:除了根结点以及叶子结点,其余剩余的结点

 子孙结点:该结点的子树的所有结点。

结点的层次:根结点在第一层,K在第四层。

树的深度:树的所有层次中最大值变为深度。

二叉树

二叉树的定义:一个根节点及两颗互不相交的,被称为”左子树“和”右子树“二叉树。

1.每个结点的度不大于2

2.每个结点只能有0,1,2个孩子,左孩子叫左子树,右孩子叫右子树

3.二叉树的五种形态

 二叉树的性质

性质1:在二叉树的第i层,层上至多有2^(i-1)个结点

性质2:深度为k的二叉树至多有2^k-1个结点

性质3:对于任意的一个二叉树T,若终端的节点数为n0,度为2的结点数n2,则no = n2+1

性质4:具有n个结点的完全二叉树的深度为|log2n|+1【高斯函数,取不大于该数值的整数】

性质5:对于具有n个结点的完全二叉树,如果完全按照对满二叉树结点进行连续编号的方式,从1开始进行序号编写

一,当i=1时,则结点为根节点,无双亲结点,若i>1,则双亲结点的序号为i/2

二,若2i<=n,则结点i的左孩子结点序号为2i,否则无左孩子结点

三,若2i+1>=n,则结点i的右孩子结点序号为2i+1,否则无右孩子结点

概念强调:

满二叉树,就是从1到k-1层的结点的度都为2,满二叉树是同样深度叶子结点最多的,也是结点最多的

完全二叉树:结点数n(n<=2^k-1),从1到n的结点结点一一满足对应关系(即都是和满二叉树完全对应)【满二叉树从最后一个结点连续的去掉任意个结点则为完全二叉树】

 二叉树的顺序存储

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define maxsize 51  //第一位存放二叉树结点个数,从而根结点序号为1,所有节点序号皆满足二叉树性质
#define elemtype char

typedef char SqBiTree[maxsize];

void InitTree(SqBiTree T)
{
 char j;
 int i;
 printf("请输入二叉树结点个数:");
 scanf("%c",&j);
 T[0]=j;
 printf("结点个数为%c\n",j);
 for(i=1;i<maxsize;i++)
 {
  T[i]='\0';
 }
}

void CreateTree(SqBiTree T,int i) //递归建立顺序二叉树
{
 fflush(stdin);
 elemtype x;
 scanf("%c",&x);
 if(x=='#')
 {
  T[i]='\0';
  return;
 }
 T[i]=x;
 printf("请输入其左子结点数据:");
 CreateTree(T,2*i);
 printf("请输入其右子结点数据:");
 CreateTree(T,2*i+1);
}

void PrintTree(SqBiTree T)
{
	int i;
 	for(i=0;i<maxsize;i++)
 	{
  		printf("%c",T[i]);
 	}
}

void main()
{
 SqBiTree t;
 InitTree(t);
 printf("请输入根节点数据:");
 CreateTree(t,1);
 PrintTree(t);
}

二叉树的链式存储结构

 1.结构体定义的初始化

//结构体初始化 
typedef struct BinaryTreeNode;
{
	struct BinaryTreeNode *left;
	struct BinaryTreeNode *right;
	char data;	
}BTNode;

2.创建一个二叉树

动态内存分配结点空间

//创建二叉树 
BTNode* CreateTreeNode(BTDataType x)
{
	BTNode *Node = (BTNode*)malloc(sizeof(BTNode));
	Node->data = x;
	Node->left = NULL;
	Node->right = NULL;
	return Node;
} 

3.前序遍历

//前序遍历 
void PreNode(BTNode *root)
{
	if(root == NULL)
	{
		printf("NULL");
		return;
	}
	printf("%c",root->data);
	PreNode(root->left);
	PreNode(root->right);
} 

图解(图来自于B站up主@青岛大学-王卓老师):

 4.中序遍历

//中序遍历 
void MidNode(BTNode *root)
{
	if(root == NULL)
	{
		printf("NULL");
		return;
	}
	MidNode(root->left);
	printf("%c",root->data);
	MidNode(root->right);
}

 图解(图来自于B站up主@青岛大学-王卓老师):

 5.后序遍历

//后序遍历 
void LastNode(BTNode *root)
{
	if(root == NULL)
	{
		printf("NULL");
		return;
	}
	PreNode(root->left);
	PreNode(root->right);
	printf("%c",root->data);
}

  图解(图来自于B站up主@青岛大学-王卓老师):

6.层序遍历

原理:每一层每一层的进行遍历,当结点出队列的同时,判断当前的结点是否有左右孩子,如果有,则将其送入队列,以此类推,知道队列为空。


void LevelTraverse(BiTree T){
    if(T != NULL)//T不是#就执行
    {
        queue<BiTree> q;//新建队列q 队内元素的类型是BiTree
        q.push(T);//T入队
        while(!q.empty())//队列不为空时就执行
        {
            BiNode* node = q.front();//取队列首个元素并赋值给node
            cout << node -> data;//输出node的值
            q.pop();//剔除队列首个元素
            
            if(node -> lchild != NULL)
                q.push(node -> lchild);//如果node的左子不为空将左子入队
            if(node -> rchild != NULL)
                q.push(node -> rchild);//如果node的右子不为空将右子入队
        }
    }
}

7.二叉树的查找:逐个结点找,找到对应需要的数据

int find(int data,Node X)
{
    if(X == NULL)
        return 0;
    if(X.data == data)
        return 1;
    int flag1 = false;
    int flag2 = false;
	flag1 = find(X.left,data);	 
	flag2 = find(X.right,data);	 
	return flag2||flag1;		 

}

8.二叉树的深度

如果是空树,递归计算左子树的深度为m,递归计算右子树深度为n,二叉树的深度为m与n的深度较大值加1。

int depth(BiTree T)
{
	if(T == NULL)
	return 0;
	else
	{
		m = depth(T->lchild);
		n = depth(T->rchild);
		if(m>n)
		return (m+1);
		else
		return (n+1);
	}
}

9.二叉树的结点计算

左子树结点的个数+右子树结点的个数+1

int NodeCount(BiTree T)
{
	if(T == NULL)
	{
		return 0;
	}
	else
	return NodeCount(T->lchild)+NodeCount(T->rchild)+1; 
}

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

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

相关文章

项目管理范围(下)

创建WBS 什么是WBS&#xff1f; WBS(Work Breakdown Structure) --- 工作分解结构 创建WBS是将项目的可交付成果和项目工作分解成较小的&#xff0c;更易于管理的组件的过程。 它包含哪些内容&#xff1f; 举例&#xff1a; 里程碑的例子&#xff1a;比如需求评审&#xff…

计算机SCI论文润色,更容易被录用吗? - 易智编译EaseEditing

SCI论文润色后投稿&#xff0c;相较于没有润色投稿&#xff0c;确实概率要大一些。 特别有些英语水平较差的作者&#xff0c;投稿的论文&#xff0c;没有润色之前&#xff0c;可能审稿人会不理解&#xff0c;或读不通。 润色后&#xff0c;可能帮助审稿人理解论文。 目前不少…

告别动态规划

一、动态规划的三大步骤 动态规划&#xff0c;无非就是利用历史记录&#xff0c;来避免我们的重复计算。而这些历史记录&#xff0c;我们得需要一些变量来保存&#xff0c;一般是用一维数组或者二维数组来保存。下面我们先来讲下做动态规划题很重要的三个步骤 第一步骤&#…

九、树结构基础

1、为什么需要树这种数据结构&#xff1f; 数组存储方式的分析 优点&#xff1a;通过下标方式访问元素&#xff0c;速度快。对于有序数组&#xff0c;还可使用二分查找提高检索速度。 缺点&#xff1a;如果要检索具体某个值&#xff0c;或者插入值(按一定顺序)会整体移动&…

简单BGP实验

&#xff08;我这里AS1 BGP为100 AS2BGP为200 AS3 BGP为300&#xff09; 这里已经配置好ip环回&#xff08;这里tcp使用的是rip也已经提前配置好&#xff09; 首先先配置AS2中的ibgp [r2]bgp 200 [r2-bgp]router-id 2.2.2.2 [r2-bgp]peer 4.4.4.4 as-number 100 [r2-bgp]…

白话初识UDP协议

UDP是什么 UDP是一个传输层的数据包装协议&#xff0c;特点有&#xff1a; 无连接&#xff08;不需要两端连通就可以发送消息给接收端&#xff09;不可靠传输&#xff08;无法知道数据是否送达&#xff09;面向数据报&#xff08;以数据报为数据传输单位&#xff09;全双工&…

vue项目cli2 升级 cli3

vue-cli2 升级 vue-cli3 由于vue-cli2 版本太低&#xff0c;升级到vue-cli3 采用的方法是新建cli3项目&#xff0c;对比差异&#xff0c;在cli2项目单独升级 检查环境 node环境检查版本是否在8.11版本以上 npm uninstall vue-cli -g 卸载旧版本的vue-cli npm install -g vue/…

广州蓝景分享—VSCode 前端开发必备插件推荐

Hello~~各位小伙伴好&#xff0c;今天广州蓝景整理一波前端开发必备插件&#xff0c;绝对可以提高你的生产力&#xff0c;希望这篇文章对大家有所帮助。 开发综合推荐 别名路径跳转 插件名&#xff1a;别名路径跳转 使用说明: 别名路径跳转插件&#xff0c;支持任何项目&…

BrightlyPro - 照片视屏后期自动调色增亮工具

BrightlyPro - 照片视屏后期自动调色增亮工具 BrightlyPro 自动增强您的照片和视频&#xff0c;你最需要它。通过一个滑块&#xff0c;BrightlyPro 立即使您的照片自适应地亮起来&#xff0c;同时保持光影之间令人愉悦的平衡&#xff0c;而不会扭曲已经点亮的区域。 下载 ➤ …

day07 面向对象

1. 类和对象 **面向对象和面向过程的思想对比 : ** ​ **面向过程 &#xff1a;**是一种以过程为中心的编程思想&#xff0c;实现功能的每一步&#xff0c;都是自己实现的 ​ **面向对象 &#xff1a;**是一种以对象为中心的编程思想&#xff0c;通过指挥对象实现具体的功能…

Java开发学习(三十四)----Maven私服(二)本地仓库访问私服配置与私服资源上传下载

一、本地仓库访问私服配置 我们通过IDEA将开发的模块上传到私服&#xff0c;中间是要经过本地Maven的 本地Maven需要知道私服的访问地址以及私服访问的用户名和密码 私服中的仓库很多&#xff0c;Maven最终要把资源上传到哪个仓库? Maven下载的时候&#xff0c;又需要携带用…

Nginx限制每秒请求次数,限制每秒连接次数,下载速度限制

Hi I’m Shendi 为了防止网站被恶意攻击&#xff0c;总是需要做一些防护措施 最外层的web服务器是Nginx&#xff0c;于是寻找 nginx 的一些关于防护措施的配置&#xff0c;记录在此 https://sdpro.top/blog/html/article/1005.html 一些变量 首先列举出会使用到的一些变量 …

XXEXML漏洞详解

XXE&XML漏洞详解1.XML基础1.1.XML基础介绍1.2.XML文档结构1.3.DTD介绍1.4.实体类介绍1.5.外部实体2.XXE漏洞基本介绍2.1.XXE漏洞基本概念2.2.XXE漏洞危害2.3.XXE漏洞输出形式2.4.XXE漏洞相关差异3.XXE漏洞测试3.1.有回显测试3.1.1.有回显案例3.1.1.1.测试回显位置3.1.1.2.构…

【XR】Oculus揭秘Touch控制器追踪技术:LED 匹配

Oculus揭秘Touch控制器追踪技术&#xff1a;LED 匹配 稳健的状态机&#xff0c;它允许我们能够在各种求解器之间进行转换 &#xff08;映维网 2019年11月05日&#xff09;映维网曾在九月分享了一篇关于Oculus Constellation追踪系统&#xff0c;其中负责AR/VR设备输入追踪的F…

动态规划——区间dp

区间dp 文章目录区间dp概述模板例题石子合并思路代码环形石子合并思路代码能量项链思路代码加分二叉树思路代码凸多边形的划分思路代码棋盘分割思路代码总结概述 区间dp就是在区间上进行动态规划&#xff0c;求解一段区间上的最优解。主要是通过合并小区间的最优解进而得出整个…

Infragistics Ignite UI for Web

Infragistics Ignite UI for Web 添加了新的透视网格组件&#xff0c;它在透视表中显示数据&#xff0c;并帮助对数据集执行复杂的分析。 使用透视网格以多维透视表结构配置和显示数据。 行和列表示不同的数据组&#xff0c;数据单元值表示聚合。 这允许基于简单的平面数据集进…

Sql Server 中FOR XML PATH(‘‘)函数用法

1. 如下表 2. 转换xml -- 将查询结果转换成xml形式 select name from zz FOR XML PATH(root);结果 说明 FOR XML PATH(‘root’)中root是xml根节点&#xff0c;所以在结果集中每条数据根节点为root&#xff0c;上面的sql将多行数据合并为一行&#xff0c;并且使用属性名name…

黑马Hive+Spark离线数仓工业项目--数仓事实层DWB层构建(3)

网点物料事实指标分析及实现 目标&#xff1a;实现DWB层网点物料事实指标表的构建 路径 - step1&#xff1a;目标需求 - step2&#xff1a;数据来源 - step3&#xff1a;目标实现 实施 - **目标需求**&#xff1a;基于物料申请单的信息统计物料申请数量、物料申请金额等…

Scriptcase配置日期字段位置日期格式的功能

Scriptcase配置日期字段位置日期格式的功能 在“翻译应用程序”工具中添加了搜索索引的快速搜索。 在项目列表屏幕上添加了垂直方向的固定条。 在登录和许可证注册屏幕上添加了显示/隐藏密码图标。 在快速编辑中添加了错误位置选项。 在Express Edit中的模式中添加了“显示字段…

电容触摸屏GT9147介绍

GT9147简介 GT9147是采用最新的电容检测技术&#xff0c;内置高性能微信号检测电路&#xff0c;可很好地解决LCD干扰和共模干扰问题。软件算法方面&#xff0c;专门基于单层互容的电气环境所设计&#xff0c;可支持5点触控。同时支持HotKnot功能 GT9147可同时识别5个触摸点位的…