C语言数据结构-二叉树的入门

文章目录

  • 0 碎碎念
  • 1 二叉树的概念和结构
    • 1.1 概念和特点
    • 1.2 结构
    • 1.3 特殊的二叉树
    • 1.4 二叉树的存储与性质
    • 1.5 前序、中序和后序
  • 2 简单二叉树的实现
    • 2.1 定义数据结构类型
    • 2.2 前序、中序和后序接口的实现
    • 2.3 二叉树中节点的个数
    • 2.4 叶子节点的个数
  • 3 完整代码块
    • 3.1 BinaryTree.h
    • 3.2 BinaryTree.c
    • 3.3 test.c


0 碎碎念

这是初学二叉树的第一节,难度不大。
本不想再记录的,毕竟刚刚学二叉树概念还是简单的。
但是想到后续难度起来了。
读者碰到难题不理解了,是不是正好可以看看笔者前面写的简单入门??
嘿嘿嘿!!!

1 二叉树的概念和结构

1.1 概念和特点

概念:一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
特点1:每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
特点2:二叉树的子树有左右之分,其子树的次序不能颠倒。

1.2 结构

现实中的二叉树
在这里插入图片描述
数据结构中的二叉树
在这里插入图片描述

1.3 特殊的二叉树

满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉
树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。

满二叉树
完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对
于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号
从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉
树。
完全二叉树

1.4 二叉树的存储与性质

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。
顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链,红黑树等会用到三叉链。

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

性质

  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1) 个结点.
  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2^h- 1.
  3. 对任何一棵二叉树, 如果度为0其叶结点个数为 n0, 度为2的分支结点个数为 n2,则有n0=n2+1
  4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h=LogN

1.5 前序、中序和后序

二叉树

前序(先根):单个节点按这样的顺序:根 左子树 右子树
从根节点开始,一直向左遍历,知道为空再找该节点的兄弟右节点,然后父节点的兄弟右节点。
A B D NULL NULL E NULL NULL C NULL NULL
中序(中根):单个节点按这样的顺序:左子树 根 右子树
左子树最左边最底层的左节点开始,其父节点,其兄弟右节点,其父节点的父节点……
NULL D NULL B NULL E NULL A NULL C NULL
后序(后根):单个节点按这样的顺序:左子树 右子树 根
左子树最左边最底层的左节点开始,其兄弟右节点,其父节点,其父节点的兄弟右节点……
NULL NULL D NULL NULL E B NULL NULLL C A

前序

中序
在这里插入图片描述

2 简单二叉树的实现

二叉树

2.1 定义数据结构类型

//定义数据结构类型
typedef char BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

2.2 前序、中序和后序接口的实现

//前序
void PrevOrder(BTNode* root)
{
	if (root == NULL) {
		printf("NULL ");
		//printf("");
		return;
	}

	printf("%c ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}
//中序
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%c ", root->data);
	InOrder(root->right);
}
//后序
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%c ", root->data);
}

在这里插入图片描述

2.3 二叉树中节点的个数

注意函数的返回类型!
注意函数的返回类型!
注意函数的返回类型!
1 三目表示式:root是空的话,节点数0,否则展开左子树+右子树+root(1)

//二叉树中节点的个数
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

2 递归思想

//这里采用全局变量size,否则TreeSize2函数多次使size归零
int size = 0;
int TreeSize2(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	else
	{
		size++;
	}
	TreeSize2(root->left);
	TreeSize2(root->right);
	return size;
}

3 size放函数里面,指针形式,这样封装健壮性就有了

void TreeSize3(BTNode* root, int* psize)
{
	if (root == NULL)
	{
		return;
	}
	else
	{
		++(*psize);
	}
	TreeSize3(root->left, psize);
	TreeSize3(root->right, psize);
}

2.4 叶子节点的个数

首先想想出现叶子节点的情况,左右子节点为空

//叶子节点的个数
int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;
	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

3 完整代码块

3.1 BinaryTree.h

#pragma once
#include<stddef.h>
#include<stdio.h>
#include<stdlib.h>
//定义数据结构类型
typedef char BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

//前序
void PrevOrder(BTNode* root);

//中序
void InOrder(BTNode* root);

//后序
void PostOrder(BTNode* root);

//二叉树中节点的个数
int TreeSize(BTNode* root);
int TreeSize2(BTNode* root);
void TreeSize3(BTNode* root, int* psize);

//叶子节点的个数
int TreeLeafSize(BTNode* root);


3.2 BinaryTree.c

#include"BinaryTree.h"
//前序
void PrevOrder(BTNode* root)
{
	if (root == NULL) {
		printf("NULL ");
		//printf("");
		return;
	}

	printf("%c ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

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

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

//二叉树中节点的个数
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

//这里采用全局变量size,否则TreeSize2函数多次使size归零
int size = 0;
int TreeSize2(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	else
	{
		size++;
	}
	TreeSize2(root->left);
	TreeSize2(root->right);
	return size;
}

void TreeSize3(BTNode* root, int* psize)
{
	if (root == NULL)
	{
		return;
	}
	else
	{
		++(*psize);
	}
	TreeSize3(root->left, psize);
	TreeSize3(root->right, psize);
}

//叶子节点的个数
int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;
	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

3.3 test.c

#include"BinaryTree.h"
int main()
{
	//定义二叉树的结构
	BTNode* A = (BTNode*)malloc(sizeof(BTNode));
	A->data = 'A';
	A->left = NULL;
	A->right = NULL;

	BTNode* B = (BTNode*)malloc(sizeof(BTNode));
	B->data = 'B';
	B->left = NULL;
	B->right = NULL;

	BTNode* C = (BTNode*)malloc(sizeof(BTNode));
	C->data = 'C';
	C->left = NULL;
	C->right = NULL;

	BTNode* D = (BTNode*)malloc(sizeof(BTNode));
	D->data = 'D';
	D->left = NULL;
	D->right = NULL;

	BTNode* E = (BTNode*)malloc(sizeof(BTNode));
	E->data = 'E';
	E->left = NULL;
	E->right = NULL;

	A->left = B;
	A->right = C;
	B->left = D;
	B->right = E;

	PrevOrder(A);
	printf("\n");
	InOrder(A);
	printf("\n");
	PostOrder(A);
	printf("\n");
	
	printf("TreeSize = %d \n", TreeSize(A));
	printf("TreeSize = %d \n", TreeSize(B));
	printf("TreeSize2=%d ", TreeSize2(A));
	
	int  Size3 = 0;
	TreeSize3(A, &Size3);
	printf("TreeSize3=%d ", Size3);

	printf("TreeLeafSize=%d\n", TreeLeafSize(A));
	printf("TreeLeafSize=%d\n", TreeLeafSize(B));

	return 0;
}


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pycharm2023安装

PyCharm是一种Python IDE&#xff08;集成开发环境&#xff09;&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外&#xff0c;该IDE提供了一些高…

亚马逊云科技发布企业生成式AI助手Amazon Q,助力企业迈向智能化时代

&#xff08;声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区、知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道&#xff09; 一、前言 随着人工智能技术的快速发展和广泛应用&#xff0c;我们…

WTF ‘Questions‘

WTF ‘Tech Team Lead’ As a Tech Team Lead, your role is to oversee the technical aspects of a project or team, and to provide guidance, support, and leadership to your team members. Here are some key responsibilities and aspects of the role: Leadership …

ChatGLM大模型推理加速之Speculative Decoding

目录 一、推测解码speculative decoding 1、自回归解码 2、speculative decoding 3、细节理解 二、核心逻辑代码 1、算法流程代码 2、模型自回归代码 a、带缓存的模型自回归实现代码 b、优化版本带缓存的模型自回归实现代码 c、ChatGLM的past_key_values的回滚 三、…

C/C++: 数据结构之索引查找(分块查找)

画图举例&#xff1a; #include<bits/stdc.h> using namespace std; /** * * Author:HackerHao * Create:2023.12.14 * */ typedef struct {int Key;int Link; }indextype;//分块查找 int IndexSequelSearch(indextype ls[], int s[], int m, int Key) //关键字为Key, 索…

云原生架构总结-读书笔记

云原生架构进阶实战-读书笔记 云原生概念 云原生&#xff08;Cloud Native&#xff09;概念是由Pivotal的Matt Stine在2013年首次提出的。这个概念得到了社区的不断完善&#xff0c;内容越来越丰富&#xff0c;目前已经**包括了DevOps&#xff08;Development和Operations的组…

云计算:Vmware 安装 FusionCompute

目录 一、理论 1.FusionCompute 二、实验 1.Vmware 安装 FusionCompute&#xff08;CNA&#xff09; 2.Vmware 安装 FusionCompute&#xff08;VRM&#xff09; 三、问题 1. VRM-WEB登录失败 2.Windows cmd中无法ping通虚拟机 一、理论 1.FusionCompute &#xff08;…

LangChain(0.0.340)官方文档九:Retrieval——Text embedding models、Vector stores、Indexing

LangChain官网、LangChain官方文档 、langchain Github、langchain API文档、llm-universe 文章目录 一、Text embedding models1.1 Embeddings类1.2 OpenAI1.3 Sentence Transformers on Hugging Face1.4 CacheBackedEmbeddings1.4.1 简介1.4.2 与Vector Store一起使用1.4.3 内…

保障事务隔离级别的关键措施

目录 引言 1. 锁机制的应用 2. 多版本并发控制&#xff08;MVCC&#xff09;的实现 3. 事务日志的记录与恢复 4. 数据库引擎的实现策略 结论 引言 事务隔离级别是数据库管理系统&#xff08;DBMS&#xff09;中的一个关键概念&#xff0c;用于控制并发事务之间的可见性。…

TikTok与虚拟现实的完美交融:全新娱乐时代的开启

TikTok&#xff0c;这个风靡全球的短视频平台&#xff0c;与虚拟现实&#xff08;VR&#xff09;技术的深度结合&#xff0c;为用户呈现了一场全新的娱乐盛宴。虚拟现实技术为TikTok带来了更丰富、更沉浸的用户体验&#xff0c;标志着全新娱乐时代的开启。本文将深入探讨TikTok…

Tomcat部署(图片和HTML等)静态资源时遇到的问题

文章目录 Tomcat部署静态资源问题图中HTML代码启动Tomcat后先确认Tomcat是否启动成功 Tomcat部署静态资源问题 今天&#xff0c;有人突然跟我提到&#xff0c;使用nginx部署静态资源&#xff0c;如图片。可以直接通过url地址访问&#xff0c;为什么他的Tomcat不能通过这样的方…

持续集成交付CICD:Jenkins使用基于SaltStack的CD流水线下载Nexus制品

目录 一、理论 1.salt常用命令 二、实验 1.SaltStack环境检查 2.Jenkins使用基于SaltStack的CD流水线下载Nexus制品 二、问题 1.salt未找到命令 2.salt简单测试报错 3. wget输出日志过长 一、理论 1.salt常用命令 &#xff08;1&#xff09;salt 命令 该 命令执行s…

回答一个同学的问题:在目前深度学习爆火的年代,专家系统还有用吗,会被淘汰吗?

文章目录 我的看法如下&#xff1a;&#xff08;不会被淘汰&#xff0c;会逐渐进化&#xff09;总结 我的看法如下&#xff1a;&#xff08;不会被淘汰&#xff0c;会逐渐进化&#xff09; 专家系统和深度学习有其各自的优势。专家系统利用规则和知识库来给出结论,适用于问题范…

There appears to be trouble with your network connection. Retrying

一直在报如上错误&#xff0c;试了很多办法&#xff0c;比如删掉yarn.lock&#xff0c;yarn cache clean&#xff0c;删掉node_modules&#xff0c;rm proxy等等都没有用 甚至于重启电脑&#xff0c;然而并没有什么用 突然间想到&#xff0c;我用了clash for window 所以想了…

Redis权限管理体系(一):客户端名及用户名

在Redis6之前的版本中&#xff0c;因安全认证的主要方式是使用Redis实例的密码进行基础控制&#xff0c;而无法按照不同的应用来源配置不同账号以及更细粒度的操作权限控制来管理。本文先从client list中的信息入手&#xff0c;逐步了解Redis的客户端名设置、用户设置及权限控制…

模型评估:压力测试 模拟对手 对齐 智能对抗 CAPTCHA(全自动区分计算机和人类的公共图灵测试)

对齐&#xff0c;智能对抗&#xff1a;魔高一尺&#xff0c;道高一丈。用更高的智能去对抗恶意使用。openAI一半的内容都在讲这个&#xff0c;但没有讲具体的方法。 如果认为对方是一个人就通过了图灵测试&#xff0c;真正的实现了智能。 如果智能达到了这种程度&#xff0c;智…

【干货分享】网工必要了解协议MPLS

热门IT技术--视频教程https://xmws-it.blog.csdn.net/article/details/134398330?spm1001.2014.3001.5502 MPLS是一种在IP骨干网上利用标签来指导数据报文高速转发的协议&#xff0c;由IETF &#xff08;Internet Engineering Task Force&#xff0c;因特网工程服务组&#xf…

2023全国职业院校技能大赛信息安全管理与评估赛项正式赛(模块二)

全国职业院校技能大赛高等职业教育组信息安全管理与评估 任务书 极安云科专注技能竞赛&#xff0c;包含网络建设与运维和信息安全管理与评估两大赛项&#xff0c;及各大CTF&#xff0c;基于两大赛项提供全面的系统性培训&#xff0c;拥有完整的培训体系。团队拥有国赛选手、大厂…

深度学习中的高斯分布

1 高斯分布数学表达 1.1 什么是高斯分布 高斯分布(Gaussian Distribution)又称正态分布(Normal Distribution)。高斯分布是一种重要的模型&#xff0c;其广泛应用与连续型随机变量的分布中&#xff0c;在数据分析领域中高斯分布占有重要地位。高斯分布是一个非常常见的连续概…

模型部署系列:10x速度提升,Yolov8检测模型稀疏化——CPU上超500FPS

YOLOv8由广受欢迎的YOLOv3和YOLOv5模型的作者 Ultralytics 开发&#xff0c;凭借其无锚设计将目标检测提升到了一个新的水平。YOLOv8 专为实际部署而设计&#xff0c;重点关注速度、延迟和经济性。 [1] 详细内容请参阅 MarkAI Blog [2] 更多资料及工程项目请关注 MarkAI Githu…