4.数据结构期末复习之树

news2024/11/23 1:04:52

1.树的概念(一对多)(要求会写遍历序列)

      1)n>=个节点,n=0时为空树
      2)仅有一个根节点
      3)左右节点互不相交,子节点一对多

2.树的特点

 1.子树之间没有关系         
 2.节点不属于多个子树(一个节点只能在一颗子树里面)
 3.没有回路(就是成环)
 4.有层次性

在这里插入图片描述

3.术语

   1.节点的度:拥有子树的个数
     树的度: 求最大值 max(树各节点的度)

在这里插入图片描述

   2.叶子节点(终端节点)                       度=0
      分支节点 (非终端节点)                   度!=0

在这里插入图片描述

       3.孩子 双亲(父节点) 兄弟 祖先(下面都是子孙)

在这里插入图片描述

  4.路径(从上到下)
             1)路径长度=经过边数-1
             2) 路是唯一的(父是唯一的)

在这里插入图片描述

   5.节点所在层数
               1)深度/高度(上下的最大节点数) 
               2)宽度(一层的左右的最大节点数)

在这里插入图片描述
3.树的遍历(对全部元素访问一遍)(没有遗漏,没有重复的访问)(从根开始访问一某种次序)(根节点在哪个位置就叫做x序遍历)

         1.前序遍历(递归)(先访问根节点,后访问左节点到右节点)
         2.后序遍历(递归)(先访问左节点到右节点,再访问根节点)
         3.层序遍历(一层一层访问)
         例如:

在这里插入图片描述
4.树的存储结构(数据元素+逻辑关系)

1.双亲表示法 (层序存储) 查双亲O(1) 查孩子O(n)查整个表,需要+firstChild优化+孩子数为O(1)

在这里插入图片描述

2.孩子表示法

1.方案1: 指针域个数=树的度(会浪费,大量的没有指向的指针)   
2.方案2: 指针域个数=节点数的度(不浪费,但是节点结构不一样)
3.方案3: 数组+指针(实用) 查孩子O(1)  查双亲O(n) +parent数组优化到O(1)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.孩子兄弟表示法(可以找孩子和兄弟)(指针指向孩子和兄弟) 找兄弟O(1) 找孩子O(n)
在这里插入图片描述

5.二叉树(考遍历序列和画树)?

1.存在空二叉树,两颗互不相交的左右子树,区分左右子树
2.二叉树不是度为2的树(对)
3.度下于等于2(错) 可能不为2
4.斜树 左斜树:只有左边的节点;右斜树:只有右边的节点 高度==节点数(一层一个节点)

在这里插入图片描述
在这里插入图片描述

6.满二叉树
特点:
1.叶子在最后一层
2.只有度= 0或2
3.同深度二叉树,他的叶子最多
4.节点数 = 2^(i) -1 (i>=0) i是层树

在这里插入图片描述7.完全二叉树(满二叉树去最后几个节点[必须是连续的n个节点])

在这里插入图片描述
在这里插入图片描述
8.二叉树的性质

  1. 如果节点度=1 一定只有一个左孩子
  2. 度 n0=n2+1;(叶子节点数=度为2 +1)
    证明: n=n0+n1+n2; (全部度相加=节点数)
    n=n1+2n2+1;(边数+1=节点数)
  3. 二叉树 第i层最多有 2^(i-1)个节点
  4. 深度=k 最多2^k -1 个节点 !!!
  5. n个节点的完全二叉树 深度=|Log2n|+1(||代表向下取整)
  6. 双亲序号 i/2 (i>1)
    i的左孩子 2i (2i<=n)
    右 2i+1 (2i+1,=n)

9.二叉树的遍历(限定先左后右)

  1. 层序遍历(之前说过了,就不重复了)
  2. 前,中,后序遍历
  3. 给一个前/中/后序列不能得到 二叉树,需要 中序+其他序 才可以 , 没有中序则不能得到二叉树
  4. 例子:

在这里插入图片描述
全部使用框框(从根开始)才容易解题.

在这里插入图片描述
10.二叉树c语言代码

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MaxSize 100
/*将二叉链表的结点结构定义和各个函数定义放到这里*/
typedef char DataType;   /*定义二叉树结点的数据类型,假设为char型*/
typedef struct BiNode {           /*定义二叉链表的结点类型*/
	DataType data;
	struct BiNode *lchild, *rchild;
} BiNode;
void PreOrder(BiNode *root) { //前序遍历
	if (root == NULL)  return;         /*递归调用的结束条件*/
	else {
		printf("%c ", root->data);        /*访问根结点的数据域,为char型*/
		PreOrder(root->lchild);          /*前序递归遍历root的左子树*/
		PreOrder(root->rchild);          /*前序递归遍历root的右子树*/
	}
}
void InOrder (BiNode *root) { //中序遍历
	if (root == NULL) return;           /*递归调用的结束条件*/
	else {
		InOrder(root->lchild);            /*中序递归遍历root的左子树*/
		printf("%c ", root->data);         /*访问根结点的数据域,为char型*/
		InOrder(root->rchild);            /*中序递归遍历root的右子树*/
	}
}

void PostOrder(BiNode *root) {//后序遍历
	if (root == NULL) return;          /*递归调用的结束条件*/
	else {
		PostOrder(root->lchild);         /*后序递归遍历root的左子树*/
		PostOrder(root->rchild);         /*后序递归遍历root的右子树*/
		printf("%c ",root->data);              /*访问根结点的数据域,为char型*/
	}
}
void LeverOrder(BiNode *root) {//层序遍历
	int rear;
	BiNode *q = NULL, *Q[MaxSize];        /*采用顺序队列*/
	//等同于定义了一个二叉树结构的队列 BiNode *Q[MaxSize];
	int front = rear = -1;                     /*初始化顺序队列*/
	if (root == NULL) return;                /*二叉树为空,算法结束*/
	Q[++rear] = root;                       /*根指针入队*/
	while (front != rear) {                   /*当队列非空时*/
		q = Q[++front];                       /*出队*/
		printf("%c ", q->data);                 /*访问结点,为char型*/
		if (q->lchild != NULL)  Q[++rear] = q->lchild;
		if (q->rchild != NULL)  Q[++rear] = q->rchild;
	}
}
int CalDepth(BiNode *root, int depth) { //得到二叉树的深度
	if (root == NULL)  return depth;         /*递归调用的结束条件*/
	else {
		int left_depth = CalDepth(root->lchild, depth + 1);
		int right_depth = CalDepth(root->rchild, depth + 1);
		return left_depth > right_depth ? left_depth : right_depth;
	}
}
int CalNodeNumber(BiNode *root){ //递归求全部节点数
	if(root == NULL) return 0;
	int count = 1;
	count += CalNodeNumber(root->lchild);
	count += CalNodeNumber(root->rchild);
	return count;
}
int CalLeafNumber(BiNode *root){//计算叶子节点数量
	if(root == NULL) return 0;
	int count = 0;
	if(root->lchild == NULL && root->rchild == NULL) count = 1;  //到空的时候才判断是叶子节点
	count += CalLeafNumber(root->lchild);
	count += CalLeafNumber(root->rchild);
	return count;
}
BiNode * CreatBiTree(BiNode *root) {
	char ch;
	scanf("%c", &ch);           /*输入结点的数据信息*/
	if (ch == '#' || ch == '\n') root = NULL;              /*递归结束,建立一棵空树*/
	else {
		root = (BiNode *)malloc(sizeof(BiNode));    /*生成新结点*/
		root->data = ch;                         /*新结点的数据域为ch*/
		printf("建立结点%c\n建立结点%c的左子树\n",ch,ch);
		root->lchild = CreatBiTree(root->lchild);           /*递归建立左子树*/
		printf("结点%c左子树建立完毕,建立其右子树\n",ch);
		root->rchild = CreatBiTree(root->rchild);           /*递归建立右子树*/
		printf("结点%c的右子树建立完毕\n",ch);
	}
	return root;
}
void DestroyBiTree(BiNode *root) {
	if (root == NULL) return;
	DestroyBiTree(root->lchild);
	DestroyBiTree(root->rchild);
	free(root);
}

int main( ) {
	BiNode *root = NULL;                  /*定义二叉树的根指针变量*/
	printf("开始建立二叉树,请输入建立序列\n");
	root = CreatBiTree(root);                  /*建立一棵二叉树*/
	printf("二叉树建立完毕\n");
	int depth = CalDepth(root, 0);
	printf("二叉树的深度是: %d\n", depth);
	
	int count = CalNodeNumber(root);
	printf("二叉树的结点数为:%d\n", count);
	
	int leaf = CalLeafNumber(root);
	printf("二叉树的叶子节点数为:%d\n", leaf);
	
	printf("该二叉树的根结点是:%c\n", root->data);
	printf("\n该二叉树的前序遍历序列是:");
	PreOrder(root);
	printf("\n该二叉树的中序遍历序列是:");
	InOrder(root);
	printf("\n该二叉树的后序遍历序列是:");
	PostOrder(root);
	printf("\n该二叉树的层序遍历序列是:");
	LeverOrder(root);
	DestroyBiTree(root);
	return 0;
}   

运行截图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

ArcGIS教程——ArcGIS快速入门

实例数据&#xff1a;https://pan.baidu.com/s/184wwCmWrJdb-qjxsT614EQ 密码&#xff1a;dowv ArcGIS for Desktop是一套完整的专业GIS应用程序&#xff0c;包含有ArcMap、ArcCatalog、ArcToolbox、ArcScense、ArcGlobe和Model Builder等。其中ArcMap、ArcCatalog、ArcToolbo…

Unreal Niagara粒子入门3 - 根据模型顶点发射粒子

在一些游戏中经常会出现根据模型顶点位置发射粒子的情况&#xff0c;这次就来实现一下该效果&#xff1a; 1.基础创建操作 首先从空粒子发射器开始创建&#xff0c;右键NiagaraSystem->Create empty system&#xff0c;打开粒子系统后再右键Add empty emitter&#xff1a…

【智能软件安全】上海道宁为您带来智能软件安全平台——​Veracode,帮助您全面地保护您构建和管理地应用程序

Veracode可以全面地 保护您构建和管理地应用程序 在现代软件 开发生命周期的 每个阶段不断发现并修复缺陷 Veracode通过 建立一种在安全和开发团队之间 架起桥梁并授权 开发人员成为 安全倡导者的积极文化 从一开始就防止常见的安全漏洞 开发商介绍 Veracode成立于20…

腾讯云8核16G服务器18M带宽CPU性能可支撑多少人同时在线?

腾讯云8核16G轻量服务器CPU性能如何&#xff1f;18M带宽支持多少人在线&#xff1f;轻量应用服务器具有100%CPU性能&#xff0c;18M带宽下载速度2304KB/秒&#xff0c;折合2.25M/s&#xff0c;系统盘为270GB SSD盘&#xff0c;月流量3500GB&#xff0c;折合每天116.6GB流量&…

【CocosCreator入门】CocosCreator组件 | TiledMap(地图)组件

Cocos Creator是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中TiledMap组件可以帮助开发者快速创建、加载和渲染地图。 目录 一、组件介绍 二、组件属性 三、脚本控制 3.1加载地图 3.2渲染地图 四、详细说明 五、关闭裁剪 六、节点遮挡 一、…

Linux中与进程间通信相关的内核数据结构

【摘要】本文详细讲述了Linux内核中与进程间通信概念相关的内核数据结构及其内在联系。 九、进程间通信(IPC)相关数据结构 9.1 ipc_namespace 从内核版本2.6.19开始&#xff0c;IPC机制已经能够意识到命名空间的存在&#xff0c;但管理IPC命名空间比较简单&#xff0c;因为它…

VR教育:让教育“可视化”,开启元宇宙教学之路

放眼世界&#xff0c;有不少高等教育学校都已经开始了元宇宙教学之路&#xff0c;为了从根本上解决目前课堂教学中存在的问题&#xff0c;进一步提高课堂教学质量&#xff0c;VR教育就可以很好地完善这些方面。 传统教育并不能让学生很好地沉浸在真实知识环境中&#xff0c;在一…

连锁门店运营管理系统有哪些功能?该如何选购?

连锁门店运营管理过程中&#xff0c;面临诸多难题&#xff0c;比如不同门店分布在不同地区&#xff0c;管理分散&#xff1b;各门店的人员管理、绩效考核、销售数据等工作进行困难&#xff1b;很难保证产品和服务的标准化管控。 连锁店只有不断适应市场变化&#xff0c;趁早选择…

不用运算符的加法运算

一.不用运算符的加法 1.题目描述 设计一个函数把两个数字相加。不得使用 或者其他算术运算符。 力扣:力扣 2.问题分析 1.知识预备 注意:下面所有的结论的进位是考虑二进制的进位,因为我们使用的位运算符,是针对二进制进行的. 结论一:在不考虑进位的情况下&#xff0c;其无…

【group by】mysql分组查询的案例和原理

【group by】mysql分组查询的案例和原理 【一】group by的使用场景【二】group by的基本语法【1】基本语法【2】常用的聚合函数&#xff08;1&#xff09;max函数&#xff1a;取出分组中的最大值&#xff08;2&#xff09;avg函数&#xff1a;取出分组中的平均值&#xff08;3&…

斩获大奖!「智办事绩效」荣获钉钉年度奖项-「含钉量新锐奖」

近日&#xff0c;钉钉发布「含钉量年度奖」榜单&#xff0c;「智办事绩效」凭借与钉钉的深度融合斩获钉钉年度奖项-「含钉量新锐奖」。 ​作为钉钉优质合作伙伴&#xff0c;智办事绩效致力于用数字化、智能化的产品与专业的服务&#xff0c;解决传统绩效管理、人才培养痛点&…

【JOSEF约瑟 JDL-5200A 电流继电器 过负荷或短路启动元件 导轨安装】

名称&#xff1a;电流继电器&#xff1b;品牌&#xff1a;JOSEF约瑟&#xff1b;型号&#xff1a;JDL-5200A触点容量&#xff1a;250V2A&#xff1b;返回时间&#xff1a;≤35ms&#xff1b;整定范围&#xff1a;0.03-19.9A&#xff1b;特点&#xff1a;返回系数高、安装方便。…

前端vue面试题

四、路由 1. Vue-Router 的懒加载如何实现 非懒加载&#xff1a; import List from /components/list.vue const router new VueRouter({routes: [{ path: /list, component: List }] })&#xff08;1&#xff09;方案一(常用)&#xff1a;使用箭头函数import动态加载 co…

content-visibility:可以提高项目的渲染性能

文章目录 一、前言二、浏览器支持程度三、CSS Containment四、跳过具有 content-visibility 的渲染工作五、关于accessibility的说明六、使用contains-intrinsic-size指定元素的自然大小七、通过content-visibility: hidden隐藏内容八、对下一幅画的交互影响(INP) 一、前言 co…

chatgpt赋能python:Python中*para:使用一个参数解决多个参数

Python中*para&#xff1a;使用一个参数解决多个参数 Python是广泛使用的编程语言之一&#xff0c;它非常灵活&#xff0c;可扩展性强&#xff0c;可以通过许多不同的方式实现编程目标。在Python中&#xff0c;有一种非常有用的特性&#xff0c;那就是使用para来代替多个参数。…

微信小程序原生开发功能合集十六:系统主页实现

本章实现小程序主页开发及对应逻辑处理,实现问卷填报相关功能,实现问卷查看、问卷查看、填报历史等功能的实现。   另外还提供小程序开发基础知识讲解课程,包括小程序开发基础知识、组件封装、常用接口组件使用及常用功能实现等内容,具体如下:    1. CSDN课程: http…

ArcGis系列-java发布GP分析结果(带样式)

1&#xff0c;前言 继上一篇 ArcGis系列-java调用GP分析 &#xff0c;已经实现了gp工具的发布&#xff0c;调用&#xff0c;轮询&#xff0c;并已经分别保存好发布地图服务所需的矢量数据json&#xff0c;栅格数据tif文件和样式文件 要将gp分析的结果发布为图层供前端展示&am…

模版的分离编译 解决方案

回顾 对于模版&#xff0c;在之前我们就已经讲过&#xff0c;模版不支持分离编译&#xff08;即声明定义不在同一文件中&#xff09;。 类中&#xff0c;我们知道&#xff0c;对于代码量比较小的函数&#xff0c;会默认识别成内联函数&#xff0c;增加代码运行的效率&#xf…

【LeetCode 142】环形链表II

思路&#xff1a; 本题需要考虑以下两个问题&#xff1a; 判断链表是否环 如果有环&#xff0c;如何找到这个环的入口 一开始想着使用双指针的办法实现&#xff0c;但是发现没有什么思路&#xff0c;后面看了一些解析&#xff0c;用的快慢指针&#xff0c;两个指针重逢了&a…

IMX6ULL裸机篇之I2C协议

一. IIC实验简介 I2C 是最常用的通信接口&#xff0c;众多的传感器都会提供 I2C 接口来和主控相连。 比如摄像头、 加速度计、触摸屏等。 I.MX6U-ALPHA开发板 使用 I2C1 接口连接了一个距离传感器 AP3216C &#xff0c;本章我们就来学习如何使用 I.MX6U 的 I2C 接口…