链式二叉树的基本操作1

1.概念回顾

讲二叉树的基本操作之前,我们回顾一下二叉树的概念

 在讲树之前,我们的每讲一种数据结构,无外乎就是在讲它们的增删查改,但是在树这里,就有了不小变化。

2.结点的定义

既然是链式二叉树,那必须得有自己的结点类型,以下是链式二叉树结点类型的定义,为了避免过多重复的代码,下面的问题都统一使用该结点类型。

typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;

创建结点 

BTNode* BuyNode(BTDataType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");return NULL;}node->data = x;node->left = NULL;node->right = NULL;return node;
}

 

 

3.二叉树的遍历

学习二叉树结构,最简单的方式就是遍历。

所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉 树中的结点进行相应的操作,并且每个节点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历 是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

讲遍历之前我们先来看基本思路啊

我们把一棵树分解成许多小树,让每个结点都成为根结点,每个根结点都有它的左右子树(可能为空),然后就像下面这样子

这样子,我们就可以按照某种特定的规则,依次对二叉 树中的每个结点进行访问左右子树的操作,并且每个节点只操作一次。

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

  • 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
  • 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
  • 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为 根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

2.1前序遍历

前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。

我们还是以这个二叉树为例来展示前序遍历

我们把代码写出来 

void PreOrder(BTNode* root) {if (root == NULL) {printf("NULL ");return;}printf("%d ", root->data);PreOrder(root->left);PreOrder(root->right);
}

我们通过代码来更深入的理解这个前序遍历

顺序我就不注明了,上面那个图有 

 3.2中序遍历

 中序遍历,又叫中根遍历。
 遍历顺序:左子树 -> 根 -> 右子树

void InOrder(BTNode* root) {if (root == NULL) {printf("NULL ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}

 

3.3后序遍历

 后序遍历,又叫后根遍历。
 遍历顺序:左子树 -> 右子树 -> 根

代码:

void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%d ", root->data);
}

 

3.4代码测试

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;BTNode* BuyNode(BTDataType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");return NULL;}node->data = x;node->left = NULL;node->right = NULL;return node;
}BTNode* CreatTree()
{BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);BTNode* node7 = BuyNode(7);node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;node3->right = node7;return node1;
}void PreOrder(BTNode* root) {if (root == NULL) {printf("NULL ");return;}printf("%d ", root->data);PreOrder(root->left);PreOrder(root->right);
}void InOrder(BTNode* root) {if (root == NULL) {printf("NULL ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%d ", root->data);
}int main()
{BTNode* root = CreatTree();PreOrder(root);printf("\n");InOrder(root);printf("\n");PostOrder(root);printf("\n");return 0;
}

 

4.结点的个数

我们采用分治的思想来统计树的结点个数,由下而上统计结点个数,遇到空结点就返回0,遇到非空结点就将其作为新的“根结点”,去访问它的左右子树,并且加1,如此以来层层递归。

int TreeSize(BTNode* root)
{return root == NULL ? 0 : TreeSize(root->left)//左子树的结点数 + TreeSize(root->right) //右子树的结点数+ 1;//根结点自己
}

5.当前树的高度

当前树的高度等于左右子树高度最大的加1

int TreeHeight(BTNode* root)
{if (root == NULL)return 0;int leftHeight = TreeHeight(root->left);int rightHeight = TreeHeight(root->right);return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}

6.第k层结点的个数

思路:
 相对于根结点的第k层结点的个数 = 相对于以其左孩子为根的第k-1层结点的个数 + 相对于以其右孩子为根的第k-1层结点的个数。

 

int TreeKLevel(BTNode* root, int k)
{assert(k > 0);if (root == NULL)return 0;if (k == 1)return 1;return TreeKLevel(root->left, k - 1)+ TreeKLevel(root->right, k - 1);
}

7.代码测试 

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;BTNode* BuyNode(BTDataType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");return NULL;}node->data = x;node->left = NULL;node->right = NULL;return node;
}BTNode* CreatTree()
{BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);BTNode* node7 = BuyNode(7);node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;node3->right = node7;return node1;
}void PreOrder(BTNode* root) {if (root == NULL) {printf("NULL ");return;}printf("%d ", root->data);PreOrder(root->left);PreOrder(root->right);
}void InOrder(BTNode* root) {if (root == NULL) {printf("NULL ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%d ", root->data);
}int TreeSize(BTNode* root)
{return root == NULL ? 0 :TreeSize(root->left)+ TreeSize(root->right)+ 1;
}int TreeHeight(BTNode* root)
{if (root == NULL)return 0;int leftHeight = TreeHeight(root->left);int rightHeight = TreeHeight(root->right);return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}int TreeKLevel(BTNode* root, int k)
{assert(k > 0);if (root == NULL)return 0;if (k == 1)return 1;return TreeKLevel(root->left, k - 1)+ TreeKLevel(root->right, k - 1);
}int main()
{BTNode* root = CreatTree();PreOrder(root);printf("\n");InOrder(root);printf("\n");PostOrder(root);printf("\n");printf("TreeSize:%d\n", TreeSize(root));printf("TreeSize:%d\n", TreeSize(root));printf("TreeSize:%d\n", TreeSize(root));printf("TreeHeight:%d\n", TreeHeight(root));printf("TreeKLevel:%d\n", TreeKLevel(root, 3));printf("TreeKLevel:%d\n", TreeKLevel(root, 4));return 0;
}

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

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

相关文章

奇安信网络安全实习一面

自我介绍数据库的几种防御方式&#xff0c;无回显怎么办&#xff1f;防御最有效的方式&#xff0c;预编译的原理&#xff1f;应急的经验&#xff08;在之前实习公司&#xff09;redis未授权怎么getshellmysql怎么获取shell做过代码审计嘛&#xff1f;java721没有链怎么办&#…

在线企业机构不可错过的开源知识付费平台!免费试用!,免费网上教学平台有哪些?怎么选择?

在线教育平台可谓如雨后春笋般&#xff0c;一个接一个的诞生。当然&#xff0c;对于学员来说&#xff0c;找在线教学平台首先是找对自己有用的&#xff0c;再者就是免费平台。其实在线教学平台免费的也有&#xff0c;不过不是每个课程都免费。这里我们一起来看看免费的在线教育…

部署 Sentinel 控制台:实现流量管理和监控

序言 Sentinel 是阿里巴巴开源的一款流量防护与监控平台&#xff0c;它可以帮助开发者有效地管理微服务的流量&#xff0c;实现流量控制、熔断降级、系统负载保护等功能。本文将介绍如何在项目中部署和配置 Sentinel 控制台&#xff0c;实现微服务的流量防护和监控。 一、Sen…

机器学习_如何给客户做聚类K-Means

文章目录 前言K-Means 的工作原理总结K-Means的实战 前言 在工作中遇见咱们给客户做下聚类&#xff0c;划分下客群&#xff0c;这里分成3类&#xff08;也可根据需求分成6类&#xff09;。根据现有的字段&#xff0c;将数值分成层级&#xff08;已处理好的数据&#xff09;&am…

深入理解Linux中TCP/IP协议栈的实现原理与具体过程

一、Linux内核与网络体系结构 在我们了解整个linux系统的网络体系结构之前&#xff0c;我们需要对整个网络体系调用&#xff0c;初始化和交互的位置&#xff0c;同时也是Linux操作系统中最为关键的一部分代码-------内核&#xff0c;有一个初步的认知。 1、Linux内核的结构 …

智能改写文章怎么做,3个方法让你轻松改出高质量文章

在如今的自媒体兴盛时代&#xff0c;内容创作对于自媒体人来说是必不可少的一项工作&#xff0c;然而&#xff0c;如何在保持内容原创性的前提下迅速生成高质量的文章变得尤为重要。智能改写文章的出现&#xff0c;为所有的自媒体人带来了一种全新的思路&#xff0c;它让大家在…

2024付费进群系统,源码及搭建变现视频课程(教程+源码)

前三节讲解搭建支付对接&#xff0c;后两节讲解一些引流变现的方法&#xff0c;还有一种变现就是帮人搭建这样的平台&#xff0c;因为全网都没有一套完整的视频教怎么搭建的&#xff0c;有也只是文字教程&#xff0c;一般新人根本看不懂&#xff0c;我视频实操演示&#xff0c;…

16-LINUX--线程安全

一。线程安全 线程安全即就是在多线程运行的时候&#xff0c;不论线程的调度顺序怎样&#xff0c;最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 要保证线程安全需要做到&#xff1a; 1&#xff09; 对线程同步&#xff0c;保证同一时刻只有一个线程访问临界资…

Java Excel操作

Apache POI是一个用于读写Microsoft Office文件格式的Java库&#xff0c;可以用来读取或写入Excel文件。 使用步骤 1.导入坐标 <!--alibaba-fastjson--> <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId>…

minio安装部署

MinIO 介绍 MinIO是一个对象存储解决方案&#xff0c;它提供了与Amazon Web Services S3兼容的API&#xff0c;并支持所有核心S3功能。 MinIO有能力在任何地方部署 - 公有云或私有云&#xff0c;裸金属基础设施&#xff0c;编排环境&#xff0c;以及边缘基础设施。 MinIO 安装…

【网络基础2】深入理解TCP协议:协议段、可靠性、各种机制

文章目录 1. TCP协议段格式1.1. 如何解包 / 向上交付1.1.1. 交付1.1.2. 解包 1.2. 如何理解可靠性1.2.1. 确认应答机制&#xff08;ACK&#xff09;1.2.2. 序号 与 确认序号 2. TCP做到全双工的原因2.1. 16位窗口大小2.2. 6个标记位 3. 如何理解连接3.1 连接管理机制3.1.1. 三次…

独孤思维:赚美金,新项目正式发布

独孤四年前开始日更写作以前&#xff0c;还做过海外赚美金项目。 当时图便宜&#xff0c;报名了国外联盟-海外问卷这个赛道。 授课老师&#xff0c;给了我一个信息表&#xff0c;让我搞了100个guge账号。 开始矩阵注册各站点&#xff0c;矩阵生成油管人身份信息。 第一阶…

安卓手机APP开发__输入事件的概述

安卓手机APP开发__输入事件的概述 目录 处理用户交互 事件监听器 onClick() onLongClick() onFocusChange() onKey() onTouch() onCreateContextMenu() 事件处理器 触摸的模式 处理焦点 处理用户交互 在安卓上,在你的应用程序上从用户的交互中发出的事件被拦截的…

VUE 继承ali-oss把我整哭了,求助帖

问题&#xff1a; npm install ali-oss 后&#xff0c; const OSS require(‘ali-oss’) // import OSS from ‘ali-oss’; 导入直接报错&#xff1a; {message: “Cannot read properties of undefined (reading ‘prototype’)”, name: “TypeError”, stack: "at 324…

Web安全研究(九)

知识星球 首先推荐一下我们的知识星球,以AI与安全结合作为主题,包括AI在安全上的应用和AI本身的安全; 加入星球你将获得: 【Ai4sec】:以数据驱动增强安全水位,涵盖内容包括:恶意软件分析,软件安全,AI安全,数据安全,系统安全,流量分析,防爬,验证码等安全方向。…

Leetcode 226:翻转二叉树

给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 思路&#xff1a;使用递归 //使用前序遍历翻转树public static TreeNode invertTree(TreeNode root){if(rootnull) return root;swap(root);invertTree(root.left);invertTree(root.rig…

API设计之争:一个接口一个职能还是一个页面所需字段?

在软件开发中&#xff0c;设计API接口是一个重要而且复杂的任务。在设计API接口时&#xff0c;一个常见的问题是&#xff0c;是按照每个接口的职能来设计&#xff0c;还是按照每个页面所需的字段来设计&#xff1f; 本文将对这两种设计方法进行比较&#xff0c;并探讨它们的优…

IP地址证书的详细申请步骤

IP地址证书申请的条件有两个&#xff0c;一个是此IP必须是公网IP&#xff0c;另一个是IP的80和443端口必须允许短暂开放。满足这两个条件才能为其部署SSL证书。 IP地址ssl证书申请网址链接https://www.joyssl.com/certificate/select/ip_certificate.html?nid16 1 访问提供IP…

2d激光slam点云滤波处理与cpu占用率

在2d激光slam 的建图定位中&#xff0c;会接收来着激光雷达传感器的数据&#xff0c;原始的点云数据是不能使用的&#xff0c;需要经过滤波处理&#xff0c;现将其常见用法步骤简述如下。 从ros话题中接收的数据会包含点云数据以及里程计数据等&#xff0c;其中对于激光雷达点云…

PyCharm安装详细教程

PyCharm安装详细教程 PyCharm简介及其下载网站 PyCharm是由JetBrains打造的一款Python IDE(Integrated Development Environment&#xff0c;集成开发环境)&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。PyCharm提供了代码编辑、调试、语法高亮…