二叉树的链式结构实现

news2024/9/20 5:10:46

二叉树的链式结构实现

    • 1. 链式存储
    • 2. 二叉树的遍历
      • 前序遍历
      • 中序遍历
      • 后序遍历
    • 3. 二叉树遍历的代码实现
      • 前序遍历
      • 中序遍历
      • 后序遍历
    • 4. 二叉树各种相关函数的实现
      • 二叉树节点个数
      • 二叉树叶子节点个数
      • 二叉树的高度
      • 二叉树第k层节点个数
      • 二叉树查找值为x的节点
    • 5. 代码验证

1. 链式存储

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。

typedef int BTDataType;
// 二叉链


typedef struct BinaryTreeNode
{
	BTDataType data;// 当前节点值域
	struct BinaryTreeNode* left;// 指向当前节点左孩子
	struct BinaryTreeNode* right;// 指向当前节点右孩子
}BTNode;

2. 二叉树的遍历

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

前序遍历

前序遍历:访问根结点的操作发生在遍历其左右子树之前

根 - > 左子树 - > 右子树

前序遍历:
在这里插入图片描述

遍历顺序:1 -> 2 -> 3 -> NULL -> NULL -> NULL -> 4 -> 5 -> NULL - >NULL6 -> NULL - >NULL 。

中序遍历

中序遍历:访问根结点的操作发生在遍历其左右子树之中。

左子树 - > 根 - > 右子树

中序遍历:
在这里插入图片描述

遍历顺序:NULL -> 3 -> NULL -> 2 -> NULL -> 1 - > NULL - > 5 - > NULL -> 4 - > NULL -> 6 -> NULL

后序遍历

后序遍历:访问根结点的操作发生在遍历其左右子树之后。

左子树 - > 右子树 - > 根

后序遍历:
在这里插入图片描述

遍历顺序:NULL -> NULL -> 3 ->NULL -> 2 - > NULL -> NULL -> 5 - > NULL -> NULL -> 6 -> 4 -> 1。

3. 二叉树遍历的代码实现

首先,要实现二叉树的遍历,我们先手动创建一棵二叉树。

和链表类似,为了方便,我们定义一个申请节点的函数。

BTNode* BuyNode(BTDataType x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));

	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	newnode->data = x;
	newnode->left = NULL;
	newnode->right = NULL;

	return newnode;
}

创建如图所示的二叉树,只需要把左右指针连接好就可以了。

在这里插入图片描述

BTNode* CreatBinary()
{
	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;
}

前序遍历

#include <stdio.h>
#include <stdlib.h>

// 二叉树前序遍历
void PrevOrder(BTNode*root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	printf("%d ", root->data);

	PrevOrder(root->left);
	PrevOrder(root->right);
}

int main()
{
	BTNode* boot = CreatBinary();
	PrevOrder(boot);
	
	return 0;
}

前序遍历递归图解:
在这里插入图片描述
在这里插入图片描述
运行结果如图:
在这里插入图片描述

中序遍历

// 二叉树中序遍历
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);
}

运行结果如图:
在这里插入图片描述

4. 二叉树各种相关函数的实现

二叉树节点个数

方法一:

求二叉树的节点个数,我们可以遍历所有节点,如果该节点不是空就计数加一,最终就可以得到二叉树节点的个数,但是注意,尽量不要在递归函数内定义变量,因为函数在递归调用的时候,开辟的空间都是独立的,我们在函数内部定义的局部变量会重复定义,所以,我们最好定义一个全局变量,这样函数递归调用的时候使用的就是同一个变量。

int size = 0;

int BTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return size;
	}
	
	size++;

	BTreeSize(root->left);
	BTreeSize(root->right);
}

方法二:
求二叉树节点的个数,可以转换为:

  1. 如果节点为空,则没有节点返回0
  2. 如果节点不为空,节点的个数 = 左子树的个数 + 右子树的个数 + 自己(1)
int BTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	return BTreeSize(root->left) + BTreeSize(root->right) + 1;
}

二叉树叶子节点个数

  1. 如果节点为,则叶子节点的个数为0,返回0
  2. 如果节点的左右指针都为空,则叶子节点的个数为1,返回1
  3. 如果不是叶子节点,也不是空节点,叶子节点的个数 = 左子树叶子节点的个数 + 右子树叶子节点的个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}
	
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

二叉树的高度

  1. 如果节点为空,则高度为0,返回0
  2. 如果节点不为空,则树的高度 = 左右子树中的较大高度的子树 + 1
int BinaryTreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	int left = BinaryTreeHeight(root->left);
	int right = BinaryTreeHeight(root->right);

	if (left > right)
	{
		return left + 1;
	}
	else
	{
		return right + 1;
	}
}

二叉树第k层节点个数

  1. 如果节点为空,则返回0
  2. 如果节点不为空,k == 1,则第k层节点个数为1,返回1
  3. 如果节点不为空,二叉树第k层节点个数 = 左子树的的第k - 1层 + 右子树的的第k - 1层
    在这里插入图片描述
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	assert(k > 0);
	
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}
	
	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

二叉树查找值为x的节点

  1. 如果节点为空,则找不到返回NULL
  2. 如果节点不为空,先看根的值是否是x,如果不是,则查找左子树和右子树是否存在节点的值为x
  3. 如果左子树找到返回左子树找到的节点,如果右子树找到返回右子树找到的节点,如果左子树和右子树都找不到,则返回NULL
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->data == x)
	{
		return root;
	}

	BTNode* ret1 = BinaryTreeFind(root->left, x);
	if (ret1)
	{
		return ret1;
	}

	BTNode* ret2 = BinaryTreeFind(root->right, x);
	if (ret2)
	{
		return ret2;
	}

	return NULL;
}

5. 代码验证

验证树的节点如图:
在这里插入图片描述
验证代码如下:

int main()
{
	BTNode* root = CreatBinary();

	printf("BinaryTreeSize : %d\n", BinaryTreeSize(root));
	printf("BinaryTreeLeafSize : %d\n", BinaryTreeLeafSize(root));
	printf("BinaryTreeHeight : %d\n", BinaryTreeHeight(root));
	printf("BinaryTreeLevelKSize : %d\n", BinaryTreeLevelKSize(root,3));

	BTNode* ret = BinaryTreeFind(root, 3);
	if (ret == NULL)
	{
		printf("找不到\n");
	}
	else
	{
		printf("找到了值为%d的节点\n", ret->data);
	}

	return 0;
}

运行结果如图:
在这里插入图片描述

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

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

相关文章

Linux系统---nginx(1)

目录 一.Nginx概述 1.定义 2.Nginx模块作用 &#xff08;1&#xff09;main模块 &#xff08;2&#xff09;stream服务模块 &#xff08;3&#xff09;邮件服务模块 &#xff08;4&#xff09;第三方模块 &#xff08;5&#xff09;events模块 &#xff08;6&#xff0…

Go的CSP并发模型实现M, P, G简介

GMP概念简介 G: goroutine&#xff08;协程&#xff0c;也叫用户态线程&#xff09; M: 工作线程(内核态线程) P: 上下文(也可以认为是cpu&#xff0c;逻辑cpu数量&#xff0c;可以在程序启动的时候设置这个数量&#xff0c;gomaxprocs函数设置) GMP 模型 在 Go 中&#xff…

力扣--动态规划1027.最长等差数列

思路分析&#xff1a; 使用动态规划的思想&#xff0c;定义二维数组dp&#xff0c;其中dp[i][j]表示以nums[i]为结尾&#xff0c;公差为(j-1000)的等差数列长度。为了适应负数的情况&#xff0c;将公差的范围设为[-1000, 1000]&#xff0c;并且加上1000作为数组索引。 初始化r…

115/200V 航空交流静变电源 115/200V机场直线加电设备

一、 115/200V 航空交流静变电源简介&#xff1a; 随着全球科技的快速发展和航空产业的不断进步&#xff0c;飞机的性能和功能要求日益提升&#xff0c;对电源设备的需求也更加严格。其中&#xff0c;“115/200V 航空交流静变电源”作为飞机的115/200V机场直线加电设备&#x…

【b站咸虾米】chapter5_uniapp-API_新课uniapp零基础入门到项目打包(微信小程序/H5/vue/安卓apk)全掌握

课程地址&#xff1a;【新课uniapp零基础入门到项目打包&#xff08;微信小程序/H5/vue/安卓apk&#xff09;全掌握】 https://www.bilibili.com/video/BV1mT411K7nW/?p12&share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 5 API 5.1 页面和路…

pytest钩子函数-pytest_runtest_logreport提取测试用例相关信息

问题&#xff1a;想在每个日志中记录测试用例开始结束时间&#xff0c;获取到测试用例的名称。 解决办法&#xff1a;使用钩子pytest_runtest_logreport 在pytest中&#xff0c;想要在conftest.py文件中获取正在运行的测试用例的名称&#xff0c;可以使用pytest_runtest_logre…

云HIS支持连锁集团化管理,1+N模式,支撑运营,管理,决策多位一体

目录 云HIS系统特色 使用简易化 连锁集团化 可扩展化 系统描述 云HIS系统优势 &#xff08;1&#xff09;客户/用户角度 &#xff08;2&#xff09;开发/运维角度 &#xff08;3&#xff09;成功应用案例 HIS分系统&#xff08;HIS子系统&#xff09; 1、医疗业务子…

马思纯后悔未反击伤害,如今瘦身重现巅峰颜值。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 近期&#xff0c;电影《热辣滚烫》在各大院线火热上映&#x…

阿里开源的Java诊断利器Arthas

一.什么是Arthas 1.为什么需要Arthas 通常&#xff0c;本地开发环境无法访问生产环境。如果在生产环境中遇到问题&#xff0c;则无法使用 IDE 远程调试。更糟糕的是&#xff0c;在生产环境中调试是不可接受的&#xff0c;因为它会暂停所有线程&#xff0c;导致服务暂停。 开…

第3集《灵峰宗论导读》

《灵峰宗论》导读。诸位法师&#xff0c;诸位同学&#xff0c;阿弥陀佛&#xff01;&#xff08;阿弥陀佛&#xff01;&#xff09; 请大家打开讲义第5面&#xff0c;悟道。 这一科我们是说明论主略史&#xff0c;在这一科当中&#xff0c;我们根据弘一大师所编的《蕅益大师年…

解析ChatGPT Plus相比chatgpt3.5有哪些优势

「ChatGPT Plus」提供更出色的对话体验和更广泛的应用能力&#xff0c;学生可以用来写作、职场人也可以用来写计划书、策划书等等&#xff0c;并且问它一些问题比搜索引擎好用多了简直。但普通人使用起来有一点门槛&#xff0c;并且升级4.0也难住了许多爱好者。 ChatGPT主要功能…

python 基础知识点(蓝桥杯python科目个人复习计划52)

今日复习内容&#xff1a;还是做题 例题1&#xff1a;四元组问题 问题描述&#xff1a; 从小学开始&#xff0c;小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期&#xff0c;他遇到了一个非常有趣的问题&#xff0c;那就算给定一个长度为n…

Webserver解决segmentation fault(core dump)段错问问题

前言 在完成了整个项目后&#xff0c;我用make命令编译了server&#xff0c;当我运行./server文件时&#xff0c;出现了段错误 在大量的代码中找出错因并不是一件容易的事&#xff0c;尤其是对新手程序员来说。而寻找bug的过程就像是侦探调查线索追查凶手一样&#xff0c;我们…

vite搭配vue2创建工程

一、安装vite npm init vite2.8.0 vite默认支持的是vue3&#xff0c; 这里选择框架和版本vanilla&#xff0c; 方便以后自己安装vue2. 二、修改package.json 默认生成的pacakage.json文件 {"name": "vite-project","private": true,"v…

AI对话系统app开源

支持对接gpt&#xff0c;阿里云&#xff0c;腾讯云 具体看截图 后端环境&#xff1a;PHP7.4MySQL5.6 软件&#xff1a;uniapp 废话不多说直接上抗揍云链接&#xff1a; https://mny.lanzout.com/iKFRY1o1zusf 部署教程请看源码内的【使用教程】文档 欢迎各位转载该帖/源码

企业过二级等保采购哪家堡垒机好?

企业常见过等保&#xff0c;一般是指等保二级或者三级。这不2024开年&#xff0c;不少企业在问&#xff0c;过二级等保采购哪家堡垒机好&#xff1f;电话多少&#xff1f;这里我们小编就给大家毛遂自荐一下吧&#xff01; 企业过二级等保采购哪家堡垒机好&#xff1f; 【回答】…

2024首场沙龙|上海 · 得物技术沙龙-「稳定生产」专场报名开启!

在互联网业界&#xff0c;伴随业务需求更新、用户流量增长、创新技术迭代&#xff0c;稳定性一直是十分复杂且极具挑战性的课题。近年业界发生较多Bad case&#xff0c;得物技术团队迎难而上&#xff0c;通过制定年度全局目标、持续技术创新、深挖产线问题、严控内建质量及文化…

第四十四回 杨雄醉骂潘巧云 石秀智杀裴如海-python驱动关系型数据库

石秀在杨雄家帮忙&#xff0c;发现杨雄的妻子潘巧云跟她的师兄、和尚裴如海有情况。 潘巧云以到寺里还愿的名义&#xff0c;去见裴如海。两人见面后&#xff0c;此处省略三百字。潘巧云说晚上如果杨雄不在家&#xff0c;就烧夜香为讯号&#xff0c;你可以来。你再找一个和尚提…

llm的inference(二)

文章目录 Tokenizer分词1.单词分词法2.单字符分词法3.子词分词法BPE(字节对编码&#xff0c;Byte Pair Encoding)WordPieceUnigram Language Model(ULM) embedding的本质推理时的一些指标参考链接 Tokenizer 在使用模型前&#xff0c;都需要将sequence过一遍Tokenizer&#xf…

AI智能分析网关V4智慧工厂视频智能监管与风险预警平台建设方案

一、背景需求分析 1&#xff09;随着信息技术的迅猛发展和制造业竞争的加剧&#xff0c;智慧工厂成为了推动制造业转型升级的重要引擎。智慧工厂解决方案通过整合物联网、人工智能、大数据分析等先进技术&#xff0c;实现生产过程的智能化、自动化和高效化&#xff0c;为企业提…