【数据结构】---几分钟简单几步学会手撕链式二叉树(上)

news2024/10/7 12:29:43

文章目录

  • 前言
  • 🌟一、二叉树链式结构的实现
    • 🌏1.1 前置说明
      • 💫快速创建一棵简单的二叉树
    • 🌏1.2 二叉树的遍历的时间、空间复杂度
    • 🌏1.3 二叉树的遍历
      • 💫1.3.1 前序、中序以及后序遍历:
      • 💫1.3.2 前序遍历:
          • 📒代码:
          • 📒流程图:
      • 💫1.3.3 后序遍历
          • 📒代码:
          • 📒流程图:
      • 💫1.3.4 中序遍历:就不画流程图了具体即上有兴趣可以自己画一下
          • 📒代码:
    • 🌏1.4 二叉树节点个数
      • 💫1.4.1 错误示范一(代码):
          • 📒代码:
          • 📒流程图:
      • 💫1.4.2 错误示范二(代码):
          • 📒代码:
          • 📒流程图:
      • 💫1.4.3 正确代码第一种(方式):定义全局变量
          • 📒代码:
          • 📒流程图:
      • 💫1.4.4 正确代码第二种(方式):
          • 📒代码:
          • 📒流程图:
  • 🌟二、全部代码:
  • 😽总结


前言

👧个人主页:@小沈熬夜秃头中୧⍤⃝❅
😚小编介绍:欢迎来到我的乱七八糟小星球🌝
📋专栏:数据结构
🔑本章内容:手撕链式二叉树
送给各位💌:我从没觉得孤独 说的浪漫点 我完全自由
记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~


提示:以下是本篇文章正文内容,下面案例可供参考

🌟一、二叉树链式结构的实现

🌏1.1 前置说明

在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,为了降低大家学习成本,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等二叉树结构了解的差不多时,我们反过头再来研究二叉树真正的创建方式。

💫快速创建一棵简单的二叉树

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* CreatBinaryTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);

	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	return node1;
}

注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式后序详解重点讲解。
再看二叉树基本操作前,再回顾下二叉树的概念:

二叉树是:

  1. 空树
  2. 非空:根节点,根节点的左子树、根节点的右子树组成的。

从概念中可以看出,二叉树定义是递归式的,因此后序基本操作中基本都是按照该概念实现的。在这里插入图片描述

🌏1.2 二叉树的遍历的时间、空间复杂度

时间复杂度:O(N)
空间复杂度:O(h)—h是高度范围是【logN,N】

🌏1.3 二叉树的遍历

💫1.3.1 前序、中序以及后序遍历:

学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

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

💫1.3.2 前序遍历:

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

📒代码:
void PrevOrder(BTNode* root)//前序
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%d ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right );
}
📒流程图:

结果:1 2 3 NULL NULL NULL 4 5 NULL NULL 6 NULL NULL在这里插入图片描述

💫1.3.3 后序遍历

(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后(左子树 -> 右子树 -> 根)。

📒代码:
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}
📒流程图:

只画了部分,具体和第一个前序一样的流程只不过注意到底是先走哪里
结果:NULL NULL 3 NULL 2 NULL NULL 5 NULL NULL 6 4 1
在这里插入图片描述

💫1.3.4 中序遍历:就不画流程图了具体即上有兴趣可以自己画一下

(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中间(左子树 -> 根 -> 右子树)。
结果:NULL 3 NULL 2 NULL 1 NULL 5 NULL 4 NULL 6 NULL

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

🌏1.4 二叉树节点个数

💫1.4.1 错误示范一(代码):

📒代码:
void BTreeSzie(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	int size = 0;
	size++;
	BTreeSzie(root->left );
	BTreeSzie(root->right );
}
📒流程图:

在这里插入图片描述

💫1.4.2 错误示范二(代码):

📒代码:

经过错误示范一想要改进就可能想到static—C语言关键字
虽然解决了size每次调用重定义的错误但是我们并不能拿到size,因为size是局部变量,为了解决这个问题,就可能想到返回值的做法,但是返回值会导致调用多次这个函数时,static一直向后面增加而外面也不能局部变量置零

int BTreeSzie(BTNode* root)
{
	static int size = 0;
	printf("%p,%d\n", &size,size);
	if (root == NULL)
	{
		return size;
	}
	size++;
	BTreeSzie(root->left );
	BTreeSzie(root->right );
	return size;
}
📒流程图:

通过打印size的地址和值可以得知static解决了错误示范一中的问题请添加图片描述

但是出现多次调用还是会出现累加现象同时不能在下一次调用这个函数时将size置零,因为它是一个局部变量。请添加图片描述

💫1.4.3 正确代码第一种(方式):定义全局变量

📒代码:
int size = 0;
void BTreeSzie(BTNode* root)
{
	if (root == NULL)
	{
		return size;
	}
	size++;
	BTreeSzie(root->left);
	BTreeSzie(root->right);
	return size;
}
📒流程图:

多次调用可以在第二次调用时将第一次数据置零请添加图片描述

💫1.4.4 正确代码第二种(方式):

📒代码:
int BTreeSzie(BTNode* root)
{
	return root == NULL ? 0 : BTreeSzie(root->left) + BTreeSzie(root->right) + 1;
}
📒流程图:

在这里插入图片描述

🌟二、全部代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
#include<stdio.h>
#include<assert.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* CreatBinaryTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);

	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	return node1;
}


void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%d ", root->data);
	PrevOrder(root->left);
	PrevOrder(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 size = 0;
//void BTreeSzie(BTNode* root)
//{
//	if (root == NULL)
//	{
//		return size;
//	}
//	size++;
//	BTreeSzie(root->left);
//	BTreeSzie(root->right);
//	return size;
//}

//int BTreeSzie(BTNode* root)
//{
//	static int size = 0;
//	//printf("%p,%d\n", &size,size);
//	if (root == NULL)
//	{
//		return size;
//	}
//	size++;
//	BTreeSzie(root->left );
//	BTreeSzie(root->right );
//	return size;
//}


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


int main()
{
	BTNode* root = CreatBinaryTree();
	PrevOrder(root);
	printf("\n");
	InOrder(root);
	printf("\n");
	PostOrder(root);
	printf("\n");
	//printf("BTreeSize:%d\n", BTreeSzie(root));
	//printf("BTreeSize:%d\n", BTreeSzie(root));
	//printf("BTreeSize:%d\n", BTreeSzie(root));
	/*BTreeSzie(root);
	printf("BTreeSize:%d\n", size);
	size = 0;
	BTreeSzie(root);
	printf("BTreeSize:%d\n", size);
	size = 0;
	BTreeSzie(root);
	printf("BTreeSize:%d\n", size);*/

	printf("BTreeSize:%d\n", BTreeSzie(root));
	return 0;
}

😽总结

请添加图片描述
😽Ending,今天的链式二叉树的内容就到此结束啦~,如果后续想了解更多,就请关注我吧,一键三连哦 ~

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

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

相关文章

深入理解hashmap底层实现原理

目录 总体介绍 HashMap元素的存储 在hashmap中添加元素 HashMap的扩容机制 HashMap的线程安全性 1.添加和删除元素时存在不安全性 2.进行扩容操作时存在不安全性 3.哈希冲突存在不安全性 4.线程之间的不可见性导致安全问题 总体介绍 HashMap是我们用于元素映射使用频率最…

MySQL——子查询

来一篇 MySQL-子查询 记录一下这个美好的时光,学习记录篇,下文中所有SQL 语句 均可在 MySQL DB 学习Demo 此处下载SQL语句执行,有相关DB 与 表。 1. 需求分析与问题解决 1.1 实际问题 现有解决方式一: SELECT salary FROM employees WHERE last_name = Abel SELECT last…

【算法】【算法杂谈】旋转数组的二分法查找

aTOC 前言 当前所有算法都使用测试用例运行过&#xff0c;但是不保证100%的测试用例&#xff0c;如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识&#xff01; 问题介绍 原问题 给定一个从小到大有序的数组&#xff0c;该数组存在重复的数&#xf…

【数据安全-02】AI打假利器数字水印,及java+opencv实现

AIGC 的火爆引燃了数字水印&#xff0c;说实话数字水印并不是一项新的技术&#xff0c;但是这时候某些公司拿出来宣传一下特别应景&#xff0c;相应股票蹭蹭地涨。数字水印是什么呢&#xff0c;顾名思义&#xff0c;和我们在pdf中打的水印作用差不多&#xff0c;起到明确版权、…

【拒绝爆零】C++编程考试常见栽区

前言 在OI赛制中&#xff0c;我们可能会因为一些细节原因导致题目爆零。下面&#xff0c;是我列举的一些常见的坑&#xff1a; 1.极值未赋值 这个错误在运行时就能检查出来&#xff0c;但还是会浪费一定的时间&#xff0c;所以我们还是避开这些小插曲为好。 2.定义变量遇到…

利用无代码工具开发一款小程序

目录 无代码工具开发小程序的流程需求分析阶段模型设计阶段页面搭建阶段创建项目创建数据表组件搭建 预览发布总结 日常我们开发小程序的时候都是要从写代码开始&#xff0c;但是写代码这个事只有专业开发才可以干&#xff0c;那作为普通人&#xff0c;如果也希望开发小程序&am…

前端小工具:批量修改图片信息

前端小工具一&#xff1a;批量修改文件夹里面的图片名称 步骤&#xff1a; 1.安装nodejs。 2.根据需要修改editFileName(filePath, formatName)函数的参数&#xff0c;也可以不改&#xff0c;直接将renameFile.js和img文件夹放在同一个目录下。 3.在renameFile.js目录下开启…

Linux:ext文件系统配额

1. 创建三个用户test1 test2 test3 2. 创建一个组 test_23 3. 把 test2 和 test3 加入test_23组 首先要有quota这个软件 如果没有用yum安装 yum -y install quota 如果不会搭建yum Linux&#xff1a;rpm查询安装 && yum安装_鲍海超-GNUBHCkalitarro的博客…

计算机组成原理-存储系统-缓存存储器(Cache)

目录 一、Cache基本概念 1.2性能分析 二、 Cache和主存的映射发生 ​​​​​​2.1全相连映射​编辑 2.2直接映射​编辑 2.3组相连映射 三、Cachae的替换算法 3.1 随机算法(RADN) 3.2 先进先出算法(FIFO) 3.3 近期最少使用(LRU) 3.4 最近不经常使用(LFU) 四、写策略 4…

kali安装ARL灯塔过程

&#xff08;一&#xff09;安装docker环境 1、检查是否存在docker环境 docker 2、如果没有docker&#xff0c;就先安装docker apt install docker.io 出现 unable to locate package docker.io这些&#xff0c;这是因为没有跟新 输入跟新命令&#xff1a; apt-get update 在…

把ChatGPT的所有插件整理成中文后!真要说卧槽了..

大家好&#xff0c;我是五竹。 ChatGPT如约向用户开放了联网功能和众多插件&#xff0c;五竹从上周开始满怀着热情等待着&#xff0c;看别人的测评效果都快把我羡慕哭了。最终等来的却是Plus账号给封了&#xff0c;而且至今也没有续上&#xff0c;只能说非常无奈。算了&#x…

探究低代码平台解决企业痛点的能力

近年来&#xff0c;随着越来越多的公司寻找改善数字化转型过程的方法&#xff0c;低代码平台的受欢迎程度一直在上升。低代码平台允许以最小的编码要求创建软件应用程序&#xff0c;从而减少与传统软件开发相关的时间和成本。今天&#xff0c;小编将聊一聊低代码平台能解决哪些…

华为设备这14个广域网命令,值得每位做广域网业务的网工收藏!

你好&#xff0c;这里是网络技术联盟站。 华为设备广域网命令是网络管理员在运维过程中常用的一类命令。该命令集涵盖了DCC配置命令、PPP配置命令、MP配置命令、PPPoE命令、ATM配置命令、帧中继配置命令、HDLC配置命令、LAPB配置命令、X.25配置命令、IP-Trunk配置命令、ISDN配…

全网最新最全面的jmeter性能测试/性能用例模板

性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。 性能测试主要包括5个方面&#xff1a; 预期目标用户测试&#xff1a;预期目标用户测试是指系统在需求分析和设计阶段都会提出一些性能指标&#xff0c;针对这些性能指标测…

微信小程序解密并拆包获取源码教程

第一步:电脑端提取微信小程序包 一般在微信安装目录下的,比如我微信安装在d盘当中,那么下载的wxapkg包就在下方 D:\qq\wechatfile\WeChat Files\Applet那么微信小程序加载的wxapkg包都在这里 比如下方的一个微信小程序的包就在这里 第二步:解密wxapkg包 工具下载地址 https:/…

人工智能-知识推理

本章可以回忆下离散中的内容&#xff0c;直接看最后的两个期末题↓。 1.基于知识的Agent 基于知识的Agent的核心是知识库KB&#xff0c;知识库中的有些语句是直接给定的而不是推导得到的为公理。基于知识的Agent使用TELL方法将新的语句添加到知识库&#xff0c;使用ASK询问来…

数据库+Python----------Python操作MySQL

目录 1.在Python中安装pymysql 2.创建数据 1.连接数据库&#xff0c;创建一个数据库对象 2.开启游标功能&#xff0c;创建游标对象 3.发送指令 获取查询结果集的方法 4.实操 5.注意 不可以&#xff01;&#xff01;&#xff01; 正确写法 6.用户输入数据 3.查询数…

设计模式之单例模式入门介绍

一、设计模式概念 设计模式是被广泛使用的软件开发中的一种解决方案&#xff0c;它提供了一套被验证过的、可重用的设计思想&#xff0c;帮助开发人员更加高效地开发出可维护、易扩展的软件系统。 设计模式可以分为三类&#xff1a;创建型模式、结构型模式和行为型模式。 1.1…

jsonschema fge json-schema-validator 高级能力 自定义类校验

入参校验产品化 schema_个人渣记录仅为自己搜索用的博客-CSDN博客 自定义的string format可以使用. 详见 fpe的 addFormatValidator ajv 的 addFormat能力 借鉴自chatgpt, 谷歌了半天,没看到好答案. Q: "jsonschema 自定义 object 校验" A: 如下 2014年后未更新…

使用 GNU 汇编语法编写 Hello World 程序的三种方法

本篇我们使用汇编来写一个经典的 Hello world 程序。 运行环境&#xff1a; OS&#xff1a;Ubuntu 18.04.5 LTS x86-64gcc&#xff1a;version 4.8.5 在用户空间编写汇编程序输出字符串&#xff0c;有三种方法&#xff1a; 调用C库函数 printf使用软中断 int 0x80使用 sysc…