当前位置: 首页 > java >正文

【数据结构初阶】--二叉树(六)

🔥个人主页:@草莓熊Lotso

🎬作者简介:C++研发方向学习者

📖个人专栏: 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。   

前言: 这篇博客将会和大家一起实现一下二叉树中的层序遍历以及判断一个二叉树是否为完全二叉树的代码实现,其中会引入队列这个数据结构的使用,中间有些需要修改的地方会特别声明大家注意一下。


目录

一.二叉树的层序遍历

准备工作:

代码实现: 

test.c: 

二.判断是否为完全二叉树

代码实现:

test.c: 

三.代码展现

Tree.h:

Tree.c:


一.二叉树的层序遍历

--我们前面实现的前中后序遍历都是属于深度优先遍历,而我们这里的层序遍历属于广义优先遍历,这里使用不了递归,我们都借助队列这个数据结构来实现,那么在实现之前有以下几个修改的地方

准备工作:

1.我们需要先把队列的.c和.h文件导入到当前vs项目中,然后在Tree.c文件里面包含上Queue.h文件

2.在Queue.h文件中我们需要把数据类型那里从int修改成二叉树节点结构类型,具体操作如图所示

代码实现: 

//二叉树的层序遍历
void LevelOrder(BTNode* root)
{Queue q;QueueInit(&q);//根节点入队QueuePush(&q, root);//遍历while (!QueueEmpty(&q)){//取队首,打印,然后出队首BTNode* top = QueueHead(&q);printf("%c ", top->data);QueuePop(&q);//将top不为空的左右孩子节点入队if (top->left){QueuePush(&q, top->left);}if (top->right){QueuePush(&q, top->right);}}QueueDestory(&q);
}

具体操作过程如图所示: 

test.c: 

#include"Tree.h"BTNode* buyNode(char x)
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));newnode->data = x;newnode->left = newnode->right = NULL;return newnode;
}
BTNode* CreateTree()
{BTNode* nodeA = buyNode('A');BTNode* nodeB = buyNode('B');BTNode* nodeC = buyNode('C');BTNode* nodeD = buyNode('D');BTNode* nodeE = buyNode('E');BTNode* nodeF = buyNode('F');nodeA->left = nodeB;nodeA->right = nodeC;nodeB->left = nodeD;nodeC->left = nodeE;nodeC->right = nodeF;return nodeA;
}void test1()
{BTNode* root = CreateTree();//前中后序遍历//PreOrder(root);//InOrder(root);//PostOrder(root);//二叉树结点个数printf("Size: %d\n", BinaryTreeSize(root));//二叉树叶子结点个数printf("LeafSize: %d\n", BinaryTreeLeafSize(root));//第k层节点个数printf("K Size: %d\n", BinaryTreeLevelKSize(root,3));//二叉树的深度/高度printf("Depth: %d\n", BinaryTreeDepth(root));//二叉树查找值为x的结点BTNode* pos = BinaryTreeFind(root, 'E');if (pos){printf("找到了\n");}else {printf("没找到\n");}//层序遍历printf("层序遍历结果:");LevelOrder(root);printf("\n");// 二叉树销毁BinaryTreeDestory(&root);
}int main()
{test1();return 0;
}

--测试完成,打印顺序没有问题,退出码为0


二.判断是否为完全二叉树

  • 完全二叉树就是除了最后一层以外其它层节点个数全部达到最大,且节点全是从左到右依次排列

代码实现:

//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root)
{Queue q;QueueInit(&q);//根节点入队QueuePush(&q, root);//遍历while (!QueueEmpty(&q)){//取队首,然后出队首BTNode* top = QueueHead(&q);QueuePop(&q);if (top == NULL){//top取到空直接出队列break;}//将top的左右孩子节点全部入队QueuePush(&q, top->left);QueuePush(&q, top->right);}//队列不为空,继续取队列中的队头while (!QueueEmpty(&q)){BTNode* top = QueueHead(&q);if (top != NULL){//有不是NULL的就不是完全二叉树QueueDestory(&q);return false;}QueuePop(&q);}QueueDestory(&q);return true;
}

 具体操作图示如下:

test.c: 

#include"Tree.h"BTNode* buyNode(char x)
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));newnode->data = x;newnode->left = newnode->right = NULL;return newnode;
}
BTNode* CreateTree()
{BTNode* nodeA = buyNode('A');BTNode* nodeB = buyNode('B');BTNode* nodeC = buyNode('C');BTNode* nodeD = buyNode('D');BTNode* nodeE = buyNode('E');BTNode* nodeF = buyNode('F');nodeA->left = nodeB;nodeA->right = nodeC;nodeB->left = nodeD;nodeC->left = nodeE;nodeC->right = nodeF;return nodeA;
}void test1()
{BTNode* root = CreateTree();//前中后序遍历//PreOrder(root);//InOrder(root);//PostOrder(root);//二叉树结点个数printf("Size: %d\n", BinaryTreeSize(root));//二叉树叶子结点个数printf("LeafSize: %d\n", BinaryTreeLeafSize(root));//第k层节点个数printf("K Size: %d\n", BinaryTreeLevelKSize(root,3));//二叉树的深度/高度printf("Depth: %d\n", BinaryTreeDepth(root));//二叉树查找值为x的结点BTNode* pos = BinaryTreeFind(root, 'E');if (pos){printf("找到了\n");}else {printf("没找到\n");}//层序遍历printf("层序遍历结果:");LevelOrder(root);printf("\n");//判断是否为完全二叉树bool iscomplete = BinaryTreeComplete(root);if (iscomplete){printf("是完全二叉树\n");}else {printf("不是完全二叉树\n");}// 二叉树销毁BinaryTreeDestory(&root);
}int main()
{test1();return 0;
}

--测试完成,没有问题,这里创建的树不是完全二叉树,退出码为0


三.代码展现

--其中队列的代码还有test.c文件(和最后一次的一样)就不展示了

Tree.h:

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef char BTDataType;
typedef struct BinaryNode
{BTDataType data;struct BinaryNode* left;//左孩子struct BinaryNode* right;//右孩子
}BTNode;//前序遍历
void PreOrder(BTNode* root);//中序遍历
void InOrder(BTNode* root);//后序遍历
void PostOrder(BTNode* root);// 二叉树结点个数
int BinaryTreeSize(BTNode* root);// 二叉树叶子结点个数
int BinaryTreeLeafSize(BTNode* root);// 二叉树第k层结点个数
int BinaryTreeLevelKSize(BTNode* root, int k);//二叉树的深度/高度
int BinaryTreeDepth(BTNode* root);// 二叉树查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);// 二叉树销毁
void BinaryTreeDestory(BTNode** root);//二叉树的层序遍历
void LevelOrder(BTNode* root);//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root);

Tree.c:

#include"Tree.h"
#include"Queue.h"//前序遍历
void PreOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}//根左右printf("%c ", root->data);PreOrder(root->left);PreOrder(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 BinaryTreeSize(BTNode* root)
{if (root == NULL){return 0;}return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}// 二叉树叶子结点个数=左子树叶子节点个数+右子树节点个数
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);
}// 二叉树第k层节点个数=左子树第K-1层节点个数+右子树第k-1层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{if (root == NULL){return 0;}//判断是否为第k层if (k == 1){return 1;}//每次注意要k-1return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}//二叉树的深度/高度=根节点+max(左子树高度,右子树高度)
int BinaryTreeDepth(BTNode* root)
{if (root == NULL){return 0;}int leftdepth = BinaryTreeDepth(root->left);int rightdepth = BinaryTreeDepth(root->right);return 1 + (leftdepth > rightdepth ? leftdepth : rightdepth);
}// 二叉树查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL){return NULL;}if (root->data == x){return root;}BTNode*leftroot = BinaryTreeFind(root->left, x);//如果leftroot不为空就是找到了直接返回if (leftroot){return leftroot;}//没找到就继续右子树找BTNode* rightroot = BinaryTreeFind(root->right, x);if (rightroot){return rightroot;}//都没找到就返回空return NULL;
}// 二叉树销毁--采用后序遍历的思想
void BinaryTreeDestory(BTNode** root)
{if (*root == NULL){return;}BinaryTreeDestory(&(*root)->left);BinaryTreeDestory(&(*root)->right);free(*root);*root = NULL;
}//二叉树的层序遍历
void LevelOrder(BTNode* root)
{Queue q;QueueInit(&q);//根节点入队QueuePush(&q, root);//遍历while (!QueueEmpty(&q)){//取队首,打印,然后出队首BTNode* top = QueueHead(&q);printf("%c ", top->data);QueuePop(&q);//将top不为空的左右孩子节点入队if (top->left){QueuePush(&q, top->left);}if (top->right){QueuePush(&q, top->right);}}QueueDestory(&q);
}//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root)
{Queue q;QueueInit(&q);//根节点入队QueuePush(&q, root);//遍历while (!QueueEmpty(&q)){//取队首,然后出队首BTNode* top = QueueHead(&q);QueuePop(&q);if (top == NULL){//top取到空直接出队列break;}//将top的左右孩子节点全部入队QueuePush(&q, top->left);QueuePush(&q, top->right);}//队列不为空,继续取队列中的队头while (!QueueEmpty(&q)){BTNode* top = QueueHead(&q);if (top != NULL){//有不是NULL的就不是完全二叉树QueueDestory(&q);return false;}QueuePop(&q);}QueueDestory(&q);return true;
}

往期回顾:

【数据结构初阶】--二叉树(二)

【数据结构初阶】--二叉树(三)

【数据结构初阶】--二叉树(四)

【数据结构初阶】--二叉树(五)

结语:我们在这篇文章中实现了链式结构二叉树的全部常用接口,其实二叉树中还有一些常考的选择题,博主这里会专门出一个特别篇带大家一起学习一下二叉树中常考的选择题,分享一下能用到的知识点,如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。

http://www.xdnf.cn/news/16785.html

相关文章:

  • 乱删文件,电脑不能开机,怎么办
  • 【C语言】深度剖析指针(三):回调机制、通用排序与数组指针逻辑
  • DeepSeek笔记(三):结合Flask实现以WEB方式访问本地部署的DeepSeek-R1模型
  • opencv解迷宫
  • 是德科技的BenchVue和纳米软件的ATECLOUD有哪些区别?
  • RabbitMQ 的死信队列完整指南 (With Spring Boot)
  • 【13】大恒相机SDK C#开发 —— Fom1中实时处理的8个图像 实时显示在Form2界面的 pictureBox中
  • 多架构镜像整合全攻略:在Docker中实现单一镜像支持同时支持amd64和arm64架构
  • 贝锐蒲公英X4 Pro 5G新品路由器:异地组网+8网口+双频WiFi全都有
  • 网站域名备案和服务器有关系吗
  • 【源力觉醒 创作者计划】文心大模型开源:从封闭研发到生态共建的转折点
  • 设计模式:命令模式 Command
  • 【Java23种设计模式】:模板方法模式
  • Windows 11下IDEA中使用git突然变得卡慢及解决办法
  • UI测试平台TestComplete如何实现从Git到Jenkins的持续测试
  • 【AI大模型】披着羊皮的狼--自动化生成越狱提示的系统(ReNeLLM)
  • thinkphp3.2 中使用redis
  • Linux应用开发基础知识——Makefile初级教程(九)
  • 分布式微服务--万字详解 微服务的各种负载均衡全场景以注意点
  • Echarts堆叠柱状图和折线图以及堆叠柱状画遇到存在极小值label数字重叠解决
  • python之使用ffmpeg下载直播推流视频rtmp、m3u8协议实时获取时间进度
  • 【qiankun】基于vite的qiankun微前端框架下,子应用的静态资源无法加载的问题
  • 进阶向:YOLOv11模型轻量化
  • 浅谈“压敏电阻”
  • 【Prompt集合】一个学习英文单词更好的提示词
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第一天(HTML5)
  • WinForm之CheckBox 控件
  • 微服务架构技巧篇——接口类设计技巧
  • 循环神经网络RNN原理精讲,详细举例!
  • 【笔记】重学单片机(51)