树二叉树

​ 树是 n(n≥0)个结点的有限集。当 n = 0时,称为空树。在任意一颗非空树中应满足:

(1)有且仅有一个特定的称为根的结点。

(2)当 n > 1时,其余结点可分为 m(m > 0)个互不相交的有限集T1, T2, …, Tm,其中每个集合本身又是一棵树,并且称为根的子树。

​ 树作为一种逻辑结构,同时也是一种分层结构,具有以下两个特点:

(1)树的根结点没有前驱,除根结点外的所有结点有且只有一个前驱。

(2)树中所有结点可以有零个或多个后继。
请添加图片描述

二叉树

​ 二叉树是另一种树形结构,其特点是每个结点至多只有两颗字数(即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。

​ 与树相似,二叉树也以递归的形式定义,二叉树是 n(n ≥ 0)个结点的有限集合:

(1)或者为空二叉树,即 n = 0。

(2)或者由一个根结点和两个互不相交的被称为根的左子树和右子树组成。左子树和右子树分别是一颗二叉树。

满二叉树:

如果一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树 。

1
2
3
4
5
6
7

完全二叉树:

深度为k,有n个节点的二叉树当且仅当其每一个节点都与深度为k的满二叉树中编号从1到n的节点一一对应时,称为完全二叉树。

1
2
3
4
5
6

普通二叉树:

1
2
3
4
5
6
7
8
9
10
A
B
D
C

二叉查找树:

二叉查找树又称二叉排序树或者二叉搜索树。

1
2
3
4
5
6
7
8
9
10
A
B
D
C

特点:

  • 每个节点上最多有两个子节点。
  • 左子树上所有节点的值都小于根节点的值。
  • 右子树上所有节点的值都大于根节点的值。

目的:

  • 提高检索数据的性能。

二茶树的链式存储

typedef char BiElemType;
typedef struct BiTNode {BiElemType data;struct BiTNode *lchild;struct BiTNode *rchild;
}

请添加图片描述

二叉树建树

#include <stdio.h>
#include <stdlib.h>typedef char BiElemType;
// 树结点
typedef struct BiTNode {// 数据BiElemType data;// 左子树struct BiTNode *lchild;// 右子树struct BiTNode *rchild;} BiTNode, *BiTree;// 用于构建辅助链队结点
typedef struct LinkNode {// 用于存储树的某一个结点的地址BiTree p_tree;struct LinkNode *next;
} LinkNode;int main() {// 创建树根BiTree Tree = NULL;// 用来指向新申请的树结点BiTree tree_new_node;// 队列头 队列尾 队列新结点 当前树的父结点(要插入结点的位置)LinkNode *q_head = NULL, *q_tail = NULL, *q_new_node = NULL, *q_cur = NULL;char c;while (scanf("%c", &c)) {if ('\n' == c) {break;}// 申请树结点// calloc 申请空间并对空间进行初始化为0tree_new_node = (BiTree) calloc(1, sizeof(BiTNode));tree_new_node->data = c;// 队列新结点q_new_node = (LinkNode *) calloc(1, sizeof(LinkNode));// 新结点p_tree存储新的树结点地址q_new_node->p_tree = tree_new_node;q_new_node->next = NULL;// 如果树为空if (NULL == Tree) {// 树根Tree = tree_new_node;// 队首q_head = q_new_node;// 队尾q_tail = q_new_node;// 当前树的父结点(要插入结点的位置)q_cur = q_new_node;// 结束本次循环continue;} else {// 新结点放入队列中q_tail->next = q_new_node;// 新结点成为新尾部q_tail = q_new_node;}// 当前父结点插入左子树if (NULL == q_cur->p_tree->lchild) {q_cur->p_tree->lchild = tree_new_node;} else if (NULL == q_cur->p_tree->rchild) {q_cur->p_tree->rchild = tree_new_node;//当前父结点左右子树都有了 队列下一个结点作为树的父结点q_cur = q_cur->next;}}return 0;
}

二叉树遍历

深度优先遍历

二叉树的深度优先遍历有三种方式,前序遍历、中序遍历、后序遍历。

  • 前序遍历是先打印自身,再打印左子树,再打印右子树。
  • 中序遍历是先打印左子树,再打印自身,再打印右子树,中序遍历相当于把树压扁。
  • 后序遍历是先打印左子树,再打印右子树,最后打印当前结点。
#include <stdio.h>
#include <stdlib.h>typedef char BiElemType;
// 树结点
typedef struct BiTNode {// 数据BiElemType data;// 左子树struct BiTNode *lchild;// 右子树struct BiTNode *rchild;} BiTNode, *BiTree;// 用于构建辅助链队结点
typedef struct LinkNode {// 用于存储树的某一个结点的地址BiTree p_tree;struct LinkNode *next;
} LinkNode;/** 先序遍历* 用递归思想解决 把每个结点看作一棵树*/
void pre_order(BiTree p) {if (NULL != p) {// 本身printf("%c", p->data);// 左子树pre_order(p->lchild);// 右子树pre_order(p->rchild);}
}/** 中序遍历* 用递归思想解决 把每个结点看作一棵树*/
void in_order(BiTree p) {if (NULL != p) {// 左子树in_order(p->lchild);// 本身printf("%c", p->data);// 右子树in_order(p->rchild);}
}/** 后续遍历* 用递归思想解决 把每个结点看作一棵树*/
void post_order(BiTree p) {if (NULL != p) {// 左子树post_order(p->lchild);// 右子树post_order(p->rchild);// 本身printf("%c", p->data);}
}int main() {// 创建树根BiTree Tree = NULL;// 用来指向新申请的树结点BiTree tree_new_node;// 队列头 队列尾 队列新结点 当前树的父结点(要插入结点的位置)LinkNode *q_head = NULL, *q_tail = NULL, *q_new_node = NULL, *q_cur = NULL;char c;while (scanf("%c", &c)) {if ('\n' == c) {break;}// 申请树结点// calloc 申请空间并对空间进行初始化为0tree_new_node = (BiTree) calloc(1, sizeof(BiTNode));tree_new_node->data = c;// 队列新结点q_new_node = (LinkNode *) calloc(1, sizeof(LinkNode));// 新结点p_tree存储新的树结点地址q_new_node->p_tree = tree_new_node;q_new_node->next = NULL;// 如果树为空if (NULL == Tree) {// 树根Tree = tree_new_node;// 队首q_head = q_new_node;// 队尾q_tail = q_new_node;// 当前树的父结点(要插入结点的位置)q_cur = q_new_node;// 结束本次循环continue;} else {// 新结点放入队列中q_tail->next = q_new_node;// 新结点成为新尾部q_tail = q_new_node;}// 当前父结点插入左子树if (NULL == q_cur->p_tree->lchild) {q_cur->p_tree->lchild = tree_new_node;} else if (NULL == q_cur->p_tree->rchild) {q_cur->p_tree->rchild = tree_new_node;//当前父结点左右子树都有了 队列下一个结点作为树的父结点q_cur = q_cur->next;}}// 先序遍历printf("Pre Order: ");pre_order(Tree);printf("\n");// 中序遍历printf("In Order: ");in_order(Tree);printf("\n");// 后序遍历printf("Post Order: ");post_order(Tree);printf("\n");return 0;
}

输入结果:

abcdefghi
Pre Order: abdhiecfg
In Order: hdibeafcg
Post Order: hidebfgcaProcess finished with exit code 0

广度优先遍历

​ 层次遍历是一种广度优先遍历,层次遍历与层次建树的原理非常相似。层次遍历必须试用辅助队列。

#include <stdio.h>
#include <stdlib.h>typedef char BiElemType;
// 树结点
typedef struct BiTNode {// 数据BiElemType data;// 左子树struct BiTNode *lchild;// 右子树struct BiTNode *rchild;} BiTNode, *BiTree;// 用于构建辅助链队结点
typedef BiTNode ElemType;
typedef struct LinkNode {ElemType *data;struct LinkNode *next;
} LinkNode;
typedef struct LinkQueue {LinkNode *front, *rear;
} LinkQueue;/** 队列初始化*/
void init_queue(LinkQueue &Q) {Q.front = Q.rear = (LinkNode *) malloc(sizeof(LinkNode));Q.front->next = NULL;
}/** 队列是否为空*/
bool queue_empty(LinkQueue Q) {return Q.front == Q.rear;
}/** 入队*/
void enqueue(LinkQueue &Q, BiTree T) {LinkNode *s = (LinkNode *) malloc(sizeof(LinkNode));s->data = T;s->next = NULL;Q.rear->next = s;Q.rear = s;
}/** 出队*/
bool dequeue(LinkQueue &Q, BiTree &T) {// 队列为空if (queue_empty(Q)) {return false;}LinkNode *p = Q.front->next;T = p->data;Q.front->next = p->next;if (Q.rear == p) {Q.rear = Q.front;}free(p);return true;
}/** 层序遍历** 跟层次建树几乎一样 用辅助队列实现*/
void level_order(BiTree T) {LinkQueue Q;init_queue(Q);// 树根入队enqueue(Q, T);// 从队列出队的树结点BiTree p;// 队列不为空while (!queue_empty(Q)) {// 出队dequeue(Q, p);putchar(p->data);// 判断当前结点是否有左孩子if (NULL != p->lchild) {// 左孩子入队enqueue(Q, p->lchild);}// 判断当前结点是否有右孩子if (NULL != p->rchild) {// 右孩子入队enqueue(Q, p->rchild);}}}int main() {// 创建树根BiTree Tree = NULL;// 用来指向新申请的树结点BiTree tree_new_node;// 队列头 队列尾 队列新结点 当前树的父结点(要插入结点的位置)LinkNode *q_head = NULL, *q_tail = NULL, *q_new_node = NULL, *q_cur = NULL;char c;while (scanf("%c", &c)) {if ('\n' == c) {break;}// 申请树结点// calloc 申请空间并对空间进行初始化为0tree_new_node = (BiTree) calloc(1, sizeof(BiTNode));tree_new_node->data = c;// 队列新结点q_new_node = (LinkNode *) calloc(1, sizeof(LinkNode));// 新结点p_tree存储新的树结点地址q_new_node->data = tree_new_node;q_new_node->next = NULL;// 如果树为空if (NULL == Tree) {// 树根Tree = tree_new_node;// 队首q_head = q_new_node;// 队尾q_tail = q_new_node;// 当前树的父结点(要插入结点的位置)q_cur = q_new_node;// 结束本次循环continue;} else {// 新结点放入队列中q_tail->next = q_new_node;// 新结点成为新尾部q_tail = q_new_node;}// 当前父结点插入左子树if (NULL == q_cur->data->lchild) {q_cur->data->lchild = tree_new_node;} else if (NULL == q_cur->data->rchild) {q_cur->data->rchild = tree_new_node;//当前父结点左右子树都有了 队列下一个结点作为树的父结点q_cur = q_cur->next;}}// 层次遍历printf("Level Order: ");level_order(Tree);return 0;
}

输出结果:

abcdefghi
Level Order: abcdefghiProcess finished with exit code 0

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

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

相关文章

基于小波的多元信号降噪-基于马氏距离和EDF统计(MATLAB R2018a)

马氏距离是度量学习中一种常用的距离指标&#xff0c;通常被用作评定数据样本间的相似度&#xff0c;可以应对高维线性分布数据中各维度间非独立同分布的问题&#xff0c;计算方法如下。 &#xff08;1&#xff09;计算样本向量的平均值。 &#xff08;2&#xff09;计算样本向…

Golang的协程调度器GMP

目录 GMP 含义 设计策略 全局队列 P的本地队列 GMP模型以及场景过程 场景一 场景2 场景三 场景四 场景五 场景六 GMP 含义 协程调度器&#xff0c;它包含了运行协程的资源&#xff0c;如果线程想运行协程&#xff0c;必须先获取P&#xff0c;P中还包含了可运行的G…

零基础直接上手java跨平台桌面程序,使用javafx(二)可视化开发Scene Builder

我们只做实用的东西&#xff0c;不学习任何理论&#xff0c;如果你想学习理论&#xff0c;请去买几大本书&#xff0c;慢慢学去。 NetBeans有可视化工具&#xff0c;但是IntelliJ IDEA对于javafx,默认是没有可视化工具的。习惯用vs的朋友觉得&#xff0c;写界面还要是有一个布局…

永久免费的iPhone,iPad,Mac,iWatch锁屏,桌面壁纸样机生成器NO.105

使用这个壁纸样机生成器&#xff0c;生成iPhone&#xff0c;iPad&#xff0c;Mac&#xff0c;iWatch锁屏&#xff0c;桌面壁纸&#xff0c;展示你的壁纸作品&#xff0c;一眼就看出壁纸好不好看&#xff0c;适不适合 资源来源于网络&#xff0c;免费分享仅供学习和测试使用&am…

归并排序的递归与非递归实现

递归实现 归并排序有点类似于二叉树的后序遍历&#xff0c;是一种基于分治思想的排序算法。具体过程如下&#xff1a; 但要注意&#xff0c;在归并时要额外开辟一个与原数组同等大小的空间用来存储每次归并排序后的值&#xff0c;然后再拷贝到原数组中。 代码实现&#xff1a…

【十大排序算法】归并排序

归并排序&#xff0c;如同秋日落叶&#xff0c;分散而细碎&#xff0c; 然而风吹叶动&#xff0c;自然而有序&#xff0c; 彼此相遇&#xff0c;轻轻合拢&#xff0c; 最终成就&#xff0c;秩序之谧。 文章目录 一、归并排序二、发展历史三、处理流程四、算法实现五、算法特性…

树莓派4B_OpenCv学习笔记5:读取窗口鼠标状态坐标_TrackBar滑动条控件的使用

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习:读取窗口鼠标状态坐标_TrackBar滑动条控件的使…

redis 05 复制 ,哨兵

01.redis的复制功能&#xff0c;使用命令slaveof 2. 2.1 2.2 3. 3.1 3.1.1 3.1.2 3.1.3 4 4.1 4.2 例子 5.1 这里是从客户端发出的指令 5.2 套接字就是socket 这里是和redis事件相关的知识 5.3 ping一下

idea编码问题:需要 <标识符> 非法的类型 、需要为 class、interface 或 enum 问题解决

目录 问题现象 问题解决 问题现象 今天在idea 使用中遇到的一个编码的问题就是&#xff0c;出现了这个&#xff1a; Error:(357, 28) java: /home/luya...........anageService.java:357: 需要 <标识符> Error:(357, 41) java: /home/luya............anageService.ja…

Cinema 4D 2024 软件安装教程、附安装包下载

Cinema 4D 2024 Cinema 4D&#xff08;C4D&#xff09;是一款由Maxon开发的三维建模、动画和渲染软件&#xff0c;广泛用于电影制作、广告、游戏开发、视觉效果等领域。Cinema 4D允许用户创建复杂的三维模型&#xff0c;包括角色、场景、物体等。它提供了多种建模工具&#x…

Channels无法使用ASGI问题

Django Channels是一个基于Django的扩展, 用于处理WebSockets, 长轮询和触发器事件等实时应用程序. 它允许Django处理异步请求, 并提供了与其他WebSockets库集成的功能.当我们在Django Channels中使用ASGI_APPLICATION设置时, 我们可以指定一个新的ASGI应用程序来处理ASGI请求.…

数据库期末设计——图书管理系统

目录 1.前置软件以及开发环境&#xff1a; 2.开发过程讲解 代码环节&#xff1a; 数据库代码 1.BookDao.java 2.BookTypeDao.java 3.UserDao.java 4.Book.java 5.BookType.java 6.User.java 7.DbUtil.java 8.Stringutil.java 9.BookAddInterFrm.java 10.BookMan…

freertos中的链表1 - 链表的数据结构

1.概述 freertos中链表的实现在 list.c 和 list.h。旨在通过学习freertos中的链表的数据结构&#xff0c;对freertos中的链表实现有一个整体的认识。freertos使用了三个数据结构来描述链表&#xff0c;分别是&#xff1a;List_t&#xff0c; MiniListItem_t&#xff0c;ListIt…

产品创新:驱动企业增长的核心动力

在当今快速变化的市场环境中&#xff0c;产品创新已成为企业生存和发展的关键。产品创新不仅涉及全新产品或服务的开发&#xff0c;也包括对现有产品或服务的持续改进和优化。本文将深入探讨产品创新的定义、重要性以及如何通过创新驱动企业增长&#xff0c;并结合实际案例进行…

Java核心: JarIndex的使用

在讲解Java类加载器的时候&#xff0c;我们发现URLClassLoader加载类或资源时通过访问ClassPath下的每一个路径&#xff0c;来确定类是否存在的&#xff0c;假设我们执行的命令是这样的 java -classpath D:\DiveInSpring\target\classes;C:\lib\spring-expression.jar;C:\lib\…

Robust Tiny Object Detection in Aerial Images amidst Label Noise

文章目录 AbstractIntroductionRelated WorkMethodsClass-aware Label CorrectionUpdateFilteringTrend-guided Learning StrategyTrend-guided Label ReweightingRecurrent Box RegenerationExperimentpaper Abstract 精确检测遥感图像中的小目标非常困难,因为这类目标视觉信…

Facebook开户|Facebook广告设计与测试优化

早上好家人们~今天Zoey给大家伙带来的是Facebook广告设计与测试优化&#xff0c;需要的家人们看过来啦&#xff01; 一、避免复杂用图和过多的文字 根据Facebook的数据显示&#xff0c;用户平均浏览一个贴文的时间在手机上仅花1.7秒、在电脑上则为2.5秒。因此&#xff0c;广告…

【Linux】进程7——进程地址空间

1.再谈fork 之前提到了fork之后对父子进程返回不同的id值&#xff0c;给父进程返回子进程的pid&#xff0c;给子进程返回0&#xff0c;所以对于一个id如何存储两个值的说法&#xff0c;在我们之前已经提到过了一个概念叫做写时拷贝&#xff0c;就是在子进程要想修改父进程的id…

首途第三十三套清新简约卡片风格蓝紫渐变色短视频模板 | 苹果CMSV10主题

首途第三十三套清新简约卡片风格蓝紫渐变色短视频模板 | 苹果CMSV10主题 我们的简约风格&#xff0c;以纯洁的白色和深邃的紫色为主色调&#xff0c;为您提供了一种清新、时尚的浏览体验。在这个简洁而美丽的界面中&#xff0c;您可以轻松畅享各种精彩短视频。我们专注于简单的…

C++命名空间的定义、C++命名空间的使用、C++输入输出等的介绍

文章目录 前言一、C命名空间的定义1. C命名空间产生的原因2. 作用域限定符3. C变量的访问顺序 二、C命名空间的使用1. 加命名空间名称及作用域限定符2. 使用using将命名空间中某个成员引入3. 使用using namespace 命名空间名称 引入4. 嵌套命名空间使用 三、 C输入&输出总结…