C语言链式二叉树、链式二叉树结构的创建、前序遍历、中序遍历、后序遍历、层序遍历来遍历二叉树、二叉树的元素个数、二叉树的高度、第K层元素的个数等的介绍

文章目录

  • 前言
  • 一、 链式二叉树结构创建
  • 二、 手动创建二叉树
  • 三、遍历二叉树
    • 1. 前序遍历
    • 2. 中序遍历
    • 3. 后序遍历
    • 4. 层序遍历
  • 四、二叉树的元素个数
  • 五、二叉树的高度(深度)
  • 六、第K层元素个数
  • 总结


前言

堆结构的实现采用的是数组实现二叉树,可以达到很好的效果。但是这种情况是基于满二叉树或者完全二叉树的情况,遇到非完全二叉树的情况,无法很好的实现,因此我们采用链式二叉树。


一、 链式二叉树结构创建

链式二叉树结构的创建

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


typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;
  • 每个节点都是由本节点的数据和左子树根元素的地址及右子树根元素的地址组成的。

因为普通链式二叉树的增删改查意义不大,所以我们只研究堆普通链式二叉树的遍历。

二、 手动创建二叉树

手动创建二叉树定义

  1. 创建一个申请节点的函数,每次申请节点的同时,初始化本节点。data为传入参数值,left 及 right 都置为空。
  2. 创建一个创建链式二叉树的函数,将每个节点的左右指针指向调整合适。
BTNode* BuyNode(BTDataType* x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("BuyNode malloc");
		return NULL;
	}

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

	return node;
}


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

int main()
{
	BTNode* root = CreateTree();
	return 0;
}
  • 因为不研究普通链式二叉树的增删改查,所以手动创建一个链式二叉树。按下图创建。

在这里插入图片描述


三、遍历二叉树

  • 遍历链式二叉树有4中方式(前序遍历,中序遍历,后序遍历,层序遍历),前三种均为递归遍历,第4种为非递归遍历。

1. 前序遍历

  • 遍历顺序
  • 前序遍历的顺序是 根元素 左子树 右子树。

前序遍历定义

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

	printf("%d ", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}
  • 递归的思想:
  • 每个节点都是按照 根元素 左子树 右子树的顺序遍历。
  • 每个函数内部都只打印本节点数据。

前序遍历测试

int main()
{
	BTNode* root = CreateTree();
	PreOrder(root);
	printf("\n");
	
	return 0;
}

效果如下
在这里插入图片描述

2. 中序遍历

  • 遍历顺序:
  • 中序遍历的顺序是 左子树 根元素 右子树。

中序遍历定义

// 中序遍历
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}
  • 递归的思想:
  • 每个节点都按照 左子树 根元素 右子树的顺序遍历。
  • 每个函数内部都只打印本节点的数据。

中序遍历测试

int main()
{
	BTNode* root = CreateTree();
	InOrder(root);
	printf("\n");
	
	return 0;
}

效果如下:
在这里插入图片描述

3. 后序遍历

  • 遍历的顺序:
  • 后序遍历的顺序是 左子树 右子树 根元素

后序遍历定义

// 后序遍历
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}

递归的思想:

  • 每个节点都是按照 左子树 右子树 根元素的顺序遍历。
  • 每个函数内部都只打印本节点数据。

后序遍历测试

int main()
{
	BTNode* root = CreateTree();
	PostOrder(root);
	printf("\n");
	
	return 0;
}

效果如下:
在这里插入图片描述

4. 层序遍历

  • 遍历的顺序:
  • 一层一层遍历。

层序遍历定义

// 层序遍历
void LevelOrder(BTNode* root)
{
	Queue q;
	// 初始化队列
	QInit(&q);

	if (root)
		QPush(&q, root);

	while (!QEmpty(&q))
	{
		BTNode* front = QFront(&q);
		QPop(&q);
		printf("%d ", front->data);

		if (front->left)
			QPush(&q, front->left);

		if (front->right)
			QPush(&q, front->right);
	}
	

	// 销毁队列
	QDestroy(&q);
}
  • 思想:
  • 使用队列,每个队列的节点数据类型都是二叉树节点(BTNode*);
  • 如若不是空节点就入队列。
  • 队列不为空,不断地出队列,若此节点的左右子树根节点都不是空,则将子树根节点入队列。
  • 简单来说就是,出上一层,带入下一层。

层序遍历测试

int main()
{
	BTNode* root = CreateTree();
	LevelOrder(root);

	return 0;
}

效果如下:
在这里插入图片描述

四、二叉树的元素个数

  • 递归的思想:
  • 每个二叉树节点都是 左子树的节点数量 + 右子树的节点数量 + 1。
  • 如若节点为空,则返回0。
    二叉树的元素个数定义
// 树的元素个数
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

二叉树的元素个数测试

int main()
{
	BTNode* root = CreateTree();
	int ret = TreeSize(root);
	printf("TreeSize:%d\n", ret);
	
	return 0;
}

效果如下:
在这里插入图片描述

五、二叉树的高度(深度)

二叉树的高度定义

  • 递归的思想:
  • 每个节点元素的高度等于本节点左右子树中高度较大的值 + 1。
  • 若节点为空,则返回0。(相当于空树返回0)。
// 树的高度
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 main()
{
	BTNode* root = CreateTree();
	int ret = TreeHeight(root);
	printf("TreeHeight: %d\n", ret);

	return 0;
}

效果如下:
在这里插入图片描述

六、第K层元素个数

第K层元素个数定义

  • 递归的思想:
  • 一个节点K层元素的个数,相当于左右子树的的 k-1 层的元素个数的和。
  • 若节点为空则返回0。(相当于空树,没有元素)。
  • 若层数为 1 则返回1, (相当于根节点在1层,只有 1 个)。
// 第K层元素个数
int TreeKLevel(BTNode* root, int k)
{
	assert(k > 0);
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
		return 1;

	int leftK = TreeKLevel(root->left, k - 1);
	int rightK = TreeKLevel(root->right, k - 1);

	return leftK + rightK;
}

第K层元素个数测试

int main()
{
	BTNode* root = CreateTree();
	ret = TreeKLevel(root, 3);
	printf("TreeKLevel: %d\n", ret);

	return 0;
}

效果如下:
在这里插入图片描述


总结

C语言链式二叉树、链式二叉树结构的创建、前序遍历、中序遍历、后序遍历、层序遍历来遍历二叉树、二叉树的元素个数、二叉树的高度、第K层元素的个数等的介绍

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

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

相关文章

数据结构栈(C语言Java语言的实现)相关习题

文章目录 栈概念以及代码实现例题[232. 用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/)[1614. 括号的最大嵌套深度](https://leetcode.cn/problems/maximum-nesting-depth-of-the-parentheses/)[234. 回文链表](https://leetcode.cn/problems/pal…

【排序算法】选择排序

一、定义&#xff1a; 选择排序&#xff08;Selection sort&#xff09;是一种简单直观的排序算法。第一次从待排序的数据&#xff08;元素&#xff09;中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在数组的起始位置&#xff0c;然后再从剩余的没有排序…

Echarts报警告Legend data should be same with series name or data name.

问题排查&#xff1a; 1. 确保 legend中的data中名字和series中每一项的name要匹配。 2. 仔细查看报警规律发现次数有在变化&#xff0c;因此找到代码中是动态修改legend,series的位置&#xff0c;检查一下这两个list的赋值逻辑。 果然&#xff0c;检查发现问题出现在了遍历里…

使用 DuckDuckGo API 实现多种搜索功能

在日常生活中&#xff0c;我经常使用搜索引擎来查找信息&#xff0c;如谷歌和百度。然而&#xff0c;当我想通过 API 来实现这一功能时&#xff0c;会发现这些搜索引擎并没有提供足够的免费 API 服务。如果有这样的免费 API, 就能定时获取“关注实体”的相关内容&#xff0c;并…

线性时间选择

给定线性序集中n个元素和一个整数k&#xff0c;1≤k≤n&#xff0c;要求找出这n个元素中第k小的元素 #include<iostream> #include<cstdlib> #include<time.h> using namespace std; int a[100]; int Random(int left,int right) {srand(time(NULL));return …

微客云霸王餐v3版本正式上线 团购霸王餐+小程序多开

好久没发布更新日志了&#xff0c;上次的更新还是春节的祝福语&#xff0c;从春节结束到现在快3个月了&#xff0c;不是说没更新内容&#xff0c;其实微客云的版本迭代一直在做&#xff0c;从后台的日志看已经发布很多版本了&#xff0c;只是没有发布文章通知&#xff0c;因为我…

算法(十二)分治算法

文章目录 算法概念算法例子字符串中小写转大写求X^n问题 算法概念 分治算法&#xff08;divide and conquer&#xff09;算法的核心思想其实就是"分而治之"&#xff0c;将原问题划分成n个规模较小&#xff0c;并且结构与原问题相似的子问题&#xff0c;递归地解决这…

鸿蒙工程目录介绍

鸿蒙构建完毕生成hhvp文件。 项目结构&#xff1a; .hvigor : 是存储构建配置文件的 .idea : 是开发工具拥有的目录 AppScope : 是全局的公共资源存放位置 hvigor &#xff1a;存放前端构建配置信息 oh_modules : 存放项目用到的第三方包 build-profile.json5 : 应用级别的构…

【MySQL数据库】:MySQL复合查询

目录 基本查询回顾 多表查询 自连接 子查询 单行子查询 多行子查询 多列子查询 在from子句中使用子查询 合并查询 前面我们讲解的mysql表的查询都是对一张表进行查询&#xff0c;在实际开发中这远远不够。 基本查询回顾 【MySQL数据库】&#xff1a;MySQL基本查…

华为telnet的两种认证方式

华为telnet的两种认证方式 实验拓扑&#xff1a; 实验要求&#xff1a; 1.采用普通密码认证实现telnet 远程登录机房设备R3 2.采用AAA认证服务方式实现telnet 远程登录机房设备R3 实验步骤&#xff1a; 1.完成基本配置&#xff08;设备接口配置IP&#xff0c;此步骤略过&#…

JVM-JAVA-类加载过程

JVM源码 类加载到 JVM 的过程通过 java 命令执行代码的流程 类加载到 JVM 的过程 在运行一个 main 函数启动程序是&#xff0c;首先需要类加载起把主类加载到 JVM 中 通过 java 命令执行代码的流程 loadClass的类加载过程有如下几步&#xff1a; 类被加载到方法区中后主要包…

视频汇聚EasyCVR安防系统对接公安部GA/T 1400视图库布控、告警、订阅流程描述

随着信息技术的飞速发展&#xff0c;视频监控在公共安全领域的应用越来越广泛&#xff0c;对于视频监控系统的要求也日益严格。为了满足公安系统对视频图像信息应用的高标准需求&#xff0c;视频汇聚平台EasyCVR视频监控系统全面支持GA/T 1400标准协议&#xff0c;为公安部门提…

【C++】——string模拟实现

前言 string的模拟实现其实就是增删改查&#xff0c;只不过加入了类的概念。 为了防止与std里面的string冲突&#xff0c;所以这里统一用String。 目录 前言 一 初始化和销毁 1.1 构造函数 1.2 析构函数 二 迭代器实现 三 容量大小及操作 四 运算符重载 4.1 bool…

03-树3 Tree Traversals Again(浙大数据结构PTA习题)

03-树3 Tree Traversals Again 分数 25 作者 陈越 An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, th…

实际测试stm32中断优先级

https://m.weibo.cn/1711020180/5040208380168258

【字典树(前缀树) 哈希映射 后序序列化】1948. 删除系统中的重复文件夹

本文涉及知识点 字典树&#xff08;前缀树) 哈希映射 后序序列化 LeetCode 1948. 删除系统中的重复文件夹 由于一个漏洞&#xff0c;文件系统中存在许多重复文件夹。给你一个二维数组 paths&#xff0c;其中 paths[i] 是一个表示文件系统中第 i 个文件夹的绝对路径的数组。 …

Codeforces Round 949 (Div. 2) (A~C)

1981A - Turtle and Piggy Are Playing a Game 贪心&#xff0c;每次取x 2&#xff0c;求最大分数 // Problem: B. Turtle and an Infinite Sequence // Contest: Codeforces - Codeforces Round 949 (Div. 2) // URL: https://codeforces.com/contest/1981/problem/B // Me…

iOS组件化 方案 实现

iOS组件化 组件化的原因现在流行的组件化方案方案一、url-block &#xff08;基于 URL Router&#xff09;方案二、protocol调用方式解读 方案三、target-action调用方式解读 gitHub代码链接参考 组件化的原因 模块间解耦模块重用提高团队协作开发效率单元测试 当项目App处于…

2024最新群智能优化算法:大甘蔗鼠算法(Greater Cane Rat Algorithm,GCRA)求解23个函数,提供MATLAB代码

一、大甘蔗鼠算法 大甘蔗鼠算法&#xff08;Greater Cane Rat Algorithm&#xff0c;GCRA&#xff09;由Jeffrey O. Agushaka等人于2024年提出&#xff0c;该算法模拟大甘蔗鼠的智能觅食行为。 参考文献 [1]Agushaka J O, Ezugwu A E, Saha A K, et al. Greater Cane Rat Alg…

LAMMPS - 分子动力学模拟器

本文翻译自&#xff1a;https://www.lammps.org/ 文章目录 一、关于 LAMMPS下载作者R&D 100 二、LAMMPS 亮点毛细血管中的血流 一、关于 LAMMPS 官网&#xff1a; https://www.lammps.org/ github &#xff1a;https://github.com/lammps/lammps LAMMPS 分子动力学模拟器…