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

news/2024/5/19 0:28:23 标签: 数据结构, 开发语言, 流程图, c语言

文章目录

  • 前言
  • 🌟一、二叉树链式结构的实现
    • 🌏1.1 二叉树叶子节点个数
    • 🌏1.2 二叉树的高度
      • 💫第一种写法(不支持):
      • 💫第二种写法:
    • 🌏1.3 二叉树第K层的节点个数
    • 🌏1.4 二叉树查找值为x的节点
      • 💫第一种写法(错误示范):
      • 💫第二种写法(正确写法):
  • 🌟二、全部代码:
  • 😽总结


前言

👧个人主页:@小沈熬夜秃头中୧⍤⃝❅
😚小编介绍:欢迎来到我的乱七八糟小星球🌝
📋专栏:数据结构
🔑本章内容:手撕链式二叉树
送给各位💌:成为更好的自己才是应该做的事
记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~


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

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

🌏1.1 二叉树叶子节点个数

💫代码:

int BTreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;
	return BTreeLeafSize(root->left) + BTreeLeafSize(root->right);
}

💫流程图

在这里插入图片描述

🌏1.2 二叉树的高度

💫第一种写法(不支持):

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

由图可知,每次比较完后并没有记录数据而是再次调用当树跃高底层最大的那个函数调用的次数就越多,所以这种方法虽然对但是耗时太长,而底层也就变成了所谓的天选打工人在这里插入图片描述

💫第二种写法:

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

每次调用都记录上数据,这样比较完直接返回大的那个+1;在这里插入图片描述

🌏1.3 二叉树第K层的节点个数

💫代码:

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

💫流程图

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

🌏1.4 二叉树查找值为x的节点

💫第一种写法(错误示范):

📒代码:
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;
	if (root->data  == x)
		return root;
	BTreeFind(root->left, x);
	BTreeFind(root->right, x);
}
📒流程图

在这里插入图片描述

💫第二种写法(正确写法):

📒代码:
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;
	if (root->data  == x)
		return root;
	BTNode* ret1 = BTreeFind(root->left, x);
	if (ret1)
		return ret1;
	BTNode* ret2 = BTreeFind(root->left, x);
	if (ret2)
		return ret2;
	return NULL;
}
📒流程图

在这里插入图片描述

🌟二、全部代码:

#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);
	BTNode* node7 = BuyNode(7);

	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	node5->left  = node7;
	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 BTreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;
	return BTreeLeafSize(root->left) 
		+ BTreeLeafSize(root->right);
}

//二叉树树的高度
int BTreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;
	int leftHeight = BTreeHeight(root->left);
	int rightHeight = BTreeHeight(root->right );
	return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}

//二叉树第k层的节点个数
int BTreeLevelKSize(BTNode* root,int k)
{
	assert(k > 1);
	if (root == NULL)
		return 0;
	if (k == 1)
		return 1;
	return BTreeLevelKSize(root->left, k - 1) 
		+ BTreeLevelKSize(root->right, k - 1);
}

//二叉树查找值为x的节点
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;
	if (root->data == x)
		return root;
	/*BTNode* ret1 = BTreeFind(root->left, x);
	if (ret1)
		return ret1;
	BTNode* ret2 = BTreeFind(root->left, x);
	if (ret2)
		return ret2;
	return NULL;*/
	//BTreeFind(root->left, x);
	//BTreeFind(root->right, x);
	//return NULL;
	BTNode* ret1 = BTreeFind(root->left, x);
	if (ret1)
		return ret1;
	return BTreeFind(root->left, x);
}

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));
	printf("BTreeLeafSize: % d\n", BTreeLeafSize(root));
	printf("BTreeHeight: % d\n", BTreeHeight(root));
	printf("BTreeLevelKSize: % d\n", BTreeLevelKSize(root,3));
	printf("BTreeLevelKSize: % d\n", BTreeLevelKSize(root,2));
	printf("BTreeLevelKSize: % d\n", BTreeLevelKSize(root, 4));
	return 0;
}

😽总结

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


http://www.niftyadmin.cn/n/365659.html

相关文章

Java学习路线(14)——Map集合类

一、介绍 概念 Map集合是一种双列集合&#xff0c;每个元素包含两个数据。元素格式&#xff1a;【keyvalue】键值对元素Map又称为 “键值对集合” Map集合格式&#xff1a; {key1value1,key2value2,key3value3,…} 二、Map集合的特点 Map家族图 1、说明&#xff1a; 使用…

vue项目实践-添加axios封装api请求

安装 axios npm install axios --save 创建实例 (utils/fetch.js) axios 默认提交格式为&#xff1a;application/json 可使用 qs 模块(需要安装)转换后提交格式为 application/x-www-form-urlencoded 通过设置 transformRequest 属性 data > qs.stringify(data) 可以正常…

打包和优化

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版&#xff0c;配图更多&#xff0c;CSDN博文图片需要手动上传&#xff0c;因此文章配图较少&#xff0c;看不懂的可以去菜鸡博客参考一下配图&#xff01; 系列文章目录 前端系列文章——传送门 后端系列文章——传送…

JavaScript 验证 API

JavaScript提供了多种验证API&#xff0c;用于验证用户输入的数据或者执行其他类型的验证操作。以下是一些常用的JavaScript验证API&#xff1a; 1. **正则表达式&#xff08;Regular Expressions&#xff09;**&#xff1a;正则表达式是一种强大的验证工具&#xff0c;用于匹…

【C++】unordered_set 和 unordered_map 使用 | 封装

文章目录 1. 使用1. unordered_set的使用2. unordered_map的使用 2. 封装修改结构定义针对insert参数 data的两种情况复用 哈希桶的insertKeyOfT模板参数的作用 迭代器operator()beginendunordered_set对于 begin和end的复用unordered_map对于 begin和end的复用unordered_map中…

Java中常量基础知识

1 问题 什么是字面常量&#xff1f; 2 方法 拿第一行输出语句来说&#xff0c;这行代码输出了 “hello” 这个字符串&#xff0c;无论何时何地运行程序&#xff0c;输出的这个字符串都不会变&#xff0c;这就是字面常量。 定义&#xff1a;常量即程序运行期间&#xff0c;固定不…

CentOS7.6(Linux)环境下有网和无网安装Docker

1、 服务器有网环境 1.1、手动卸载旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine1.2、安装yum-utils sudo yum install -y yum-utils \device-mapper-per…

使用qemu模拟CXL.mem设备

CXL可以说是自PCIe技术诞生几十年以来最具变革性的新技术了。可以想象有了CXL以后机箱的边界将被彻底打破&#xff0c;服务器互相使用对方的内存&#xff0c;网卡&#xff0c;GPU 。整个机架甚至跨机架的超级资源池化成为可能&#xff0c;云计算也将进入一个新的时代。 当前In…