【数据结构初阶 7】二叉树:链式二叉树的基本操作实现

文章目录

  • 🌈 Ⅰ 定义二叉树结点
  • 🌈 Ⅱ 创建二叉树结点
  • 🌈 Ⅲ 遍历二叉树
    • 1. 先序遍历
    • 2. 中序遍历
    • 3. 后序遍历
    • 4. 层序遍历
  • 🌈 Ⅳ 销毁二叉树

🌈 Ⅰ 定义二叉树结点

1. 每个结点都由三部分组成

  1. 数据域:存储本结点的数据。
  2. 左孩子域:存储该结点左孩子的地址,即指向该结点左子树的根结点。
  3. 右孩子域:存储该结点右孩子的地址,即指向该结点右子树的根结点。

在这里插入图片描述

2. 定义二叉树结点

typedef int BTDataType;typedef struct TreeNode			// 树结点
{BTDataType data;			// 数据域struct TreeNode* lchild;	// 左孩子域struct TreeNode* rchild;	// 右孩子域
}TreeNode;

🌈 Ⅱ 创建二叉树结点

  • malloc 一个新结点,然后将数据放进该结点数据域,新结点左右孩子都为空。
TreeNode* BuyTreeNode(int x)
{TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));assert(node);node->data = x;						node->lchild = node->rchild = NULL;	// 新结点的左右孩子域都为空return node;
}

🌈 Ⅲ 遍历二叉树

递归遍历的结束条件

  • 当递归到某个结点为 NULL 时返回,计算机不知道哪个结点为叶子结点,只有当递归到某个结点的左右孩子域都为 NULL 时才能确定该结点为叶结点。

在这里插入图片描述

1. 先序遍历

  1. 对于一棵二叉树,其中任意一棵子树都按照根结点、左子树、右子树的顺序访问。
  2. 访问完当前结点后就去访问其左子树,左子树访问完后就去访问该结点右子树。
  3. 对于该结点左右子树的访问方式和第二步一致。

在这里插入图片描述

// 先序遍历
void TreePrevOrder(TreeNode* root)
{if (NULL == root)					// 结点为空时返回{return;}printf("%d ", root->data);		// 先访问当前结点TreePrevOrder(root->lchild);	// 当前结点访问完了就去访问左子树TreePrevOrder(root->rchild);	// 左子树也访问完了最后去访问右子树
}

2. 中序遍历

  • 按照 左子树 → 当前结点 → 右子树 的顺序访问树中的每棵子树。
  • 对于树中的任意结点,在访问完该结点的左子树之前都不能访问该结点。

在这里插入图片描述

// 中序遍历
void TreeInOrder(TreeNode* root)
{if (NULL == root){return;}TreePrevOrder(root->lchild);	// 优先访问当前结点的左子树printf("%d ", root->data);		// 访问完当前结点的左子树后才能访问该结点TreePrevOrder(root->rchild);	// 最后才能去访问右子树
}

3. 后序遍历

  • 按照 左子树 → 右子树 → 当前结点 的顺序访问树中的每棵子树。
  • 对于树中的任意结点,在访问完该结点的左子树和右子树之前都不能访问该结点。

在这里插入图片描述

// 后续遍历
void TreePostOrder(TreeNode* root)
{if (NULL == root){return;}TreePrevOrder(root->lchild);	// 优先访问当前结点的左子树TreePrevOrder(root->rchild);	// 然后访问当前结点的右子树printf("%d ", root->data);		// 最后才能访问当前结点
}

4. 层序遍历

实现思路

  • 借助队列进行层次遍历。
  • 将当前结点放入队列,然后出队列。
  • 出队列时,该结点还要顺带将其非空的左右孩子结点也入队列。
  • 等到队列为空时,这样出队列的结点顺序就是二叉树的层序遍历结果。

举个例子

在这里插入图片描述

实现代码

void TreeLevelOrder(TreeNode* root)
{Queue q;								// 创建队列QueueInit(&q);							// 队列初始化if (root != NULL)						// 将非空结点入队列{QueuePush(&q, root);}int LevelSize = 1;						// 用来记录每层结点的个数while (!QueueEmpty(&q))					// 队列非空时二叉树没有遍历完{while (LevelSize--)					// 控制一层一层输出结点{TreeNode* front = QueueFront(&q);QueuePop(&q);					// 队头结点出队列printf("%d ", front->data);		// 打印队头结点的值if (front->left != NULL)		// 出队时将其非空左孩子结点入队{QueuePush(&q, front->left);}if (front->right != NULL)		// 出队时将其非空右孩子结点入队{QueuePush(&q, front->right);}}printf("\n");						// 输出完一层的结点就换行LevelSize = QueueSize(&q);			// 队列内元素个数就是下一层结点数}QueueDestroy(&q);						// 销毁队列
}

🌈 Ⅳ 销毁二叉树

  • 采用后序的方式删除二叉树,先删完左右子树再删根结点。
  • 对于树中的每棵子树都采用上述方法。
void TreeDestory(TreeNode* root)
{if (NULL == root){return;}TreeDestory(root->lchild);	// 先删左子树TreeDestory(root->rchild);	// 再删右子树free(root);					// 最后删根结点
}

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

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

相关文章

matlab绘制雷达图和二维FFT变换图

1、内容简介 略 49-可以交流、咨询、答疑 matlab绘制雷达图和二维FFT变换图 NMO组及NORMAL组 RNFL层、GCL层、IPL层、GCC层、ORL层做雷达图(共10张) 2、内容说明 略 NMO组及NORMAL组 RNFL层、GCL层、IPL层、GCC层、ORL层请分别做雷达图&#xff08…

linux之前后端项目部署与发布

目录 前言 简介 一、安装Nginx 二、后端部署 2.1多个tomcat负载均衡 2.2 负载均衡 2.3 后端项目部署 三、前端部署 1.解压前端 2.Nginx配置文件修改 3.IP域名映射 4.重启Nginx服务 前言 上篇博主已经讲解过了单机项目的部署linux之JAVA环境配置JDK&Tomcat&a…

Linux基础命令—系统服务

基础知识 centos系统的开机流程 1)通电 2)BIOS硬件检查 3)MBR引导记录 mbr的引导程序 加载引导程序 让硬件加载操作系统内核 MBR在第一个磁盘第一个扇区 总大小512字节 mbr: 1.引导程序: 占用446字节用于引导硬件,加载引导程序 2.分区表: 总共占…

文献阅读:Large Language Models are Null-Shot Learners

文献阅读:Large Language Models are Null-Shot Learners 1. 文章简介2. 方法介绍3. 实验考察 & 结论 1. 基础实验 1. 实验设计2. 实验结果 2. 消融实验 1. 小模型上的有效性2. ∅CoT Prompting3. 位置影响4. 组成内容 4. 总结 & 思考 文献链接&#xff1…

Zookeeper客户端命令、JAVA API、监听原理、写数据原理以及案例

1. Zookeeper节点信息 指定服务端,启动客户端命令: bin/zkCli.sh -server 服务端主机名:端口号 1)ls / 查看根节点下面的子节点 ls -s / 查看根节点下面的子节点以及根节点详细信息 其中,cZxid是创建节点的事务id&#xff0c…

Python 鼠标模拟

鼠标模拟即:通过python 进行模拟鼠标操作 引入类库 示例如下: import win32api import win32con import time 设置鼠标位置 设置鼠标位置为窗口中的回收站。 示例如下: # 设置鼠标的位置 win32api.SetCursorPos([30, 40]) 双击图标 设置…

vue:find查找函数实际开发的使用

find的作用: find 方法主要是查找数组中的属性,会遍历数组,对每一个元素执行提供的函数,直到找到使该函数返回 true 的元素。然后返回该元素的值。如果没有元素满足测试函数,则返回 undefined。 基础使用&#xff1a…

五、数组——Java基础篇

六、数组 1、数组元素的遍历 1.1数组的遍历:将数组内的元素展现出来 1、普通for遍历:根据下表获取数组内的元素 2、增强for遍历: for(数据元素类型 变量名:数组名){ 变量名:数组内的每一个值…

python统计分析——多解释变量的方差分析

参考资料:用python动手学统计学 1、导入库 # 导入库 # 用于数值计算的库 import numpy as np import pandas as pd import scipy as sp from scipy import stats # 用于绘图的库 from matplotlib import pyplot as plt import seaborn as sns sns.set() # 用于估计…

docker-compose 搭建laravel环境

laravel环境包含nginx,mysql,php7.4,redis 一、安装好docker后pull镜像 1.nginx镜像 docker pull nginx:latest单独启动容器 docker run --name nginx -p 80:80 -d nginx 2.php镜像 docker pull php:7.4-fpm3.mysql镜像 docker pull mysql:5.74.redis镜像 docker pull r…

高频面试题整理(一)

文章目录 平台无关性如何实现?JVM如何加载 .class文件?什么是反射?谈谈ClassLoader谈谈类的双亲委派机制类的加载方式Java的内存模型?JVM内存模型-jdk8程序计数器:Java虚拟机栈局部变量表和操作数栈: Java内存模型中堆和栈的区别…

Linux部署前后端分离项目

目录 一、jdk安装 二、tomcat安装 三、MySQL安装 四、nginx安装 五、配置多个tomcat负载,部署后端项目 六、前端部署 一、jdk安装 1. 上传jdk安装包 jdk-8u151-linux-x64.tar.gz 进入opt目录,将安装包拖进去 2. 解压安装包 这里需要解压到usr/loc…