目录
二叉树的实现
文件名 | 功能简介 |
---|---|
BinTreeAlgo.h | 定义二叉树操作接口(初始化,遍历,插入,删除等)以及其辅助函数 |
BinTreeDef.h | 定义二叉树节点结构(数据、左右孩子)和二叉树公共类型 |
pubuse.h | 通用头文件,包含全局定义(全局变量、预处理器宏、函数库等) |
BinTreeUse.cpp | 用户界面实现,提供图形化菜单操作与二叉树的基本操作(如创建、删除、查询与遍历) |
总结:程序整体功能是,通过用户交互式操作,实现对二叉树结构的创建、管理(插入、删除),并能展示其遍历结果,旨在演示和学习二叉树数据结构的典型应用。
这个项目包含一组C++文件,包括定义二叉树结构、接口和操作函数的头文件(BinTreeAlgo.h, BinTreeDef.h),全局公共使用的头文件(pubuse.h),以及利用这些结构进行用户交互操作的实现代码(BinTreeUse.cpp),整体上实现了二叉树数据结构的基础操作演示。
项目获取
所有代码已经上传到CSDN,通过资源绑定功能,已经绑定本篇博客,有需要请自取,完整的VS2022项目,运行“数据结构-二叉树.sln”即可在vs2022中打开(一般来说,版本无限制)
在我上传时,设置了0积分,可以免费获取,但不保证后续积分要求会不会变化(但放心,不会变成付费或会员专享资源),不过,还请尽快保存!
具体实现解析
pubuse.h
的头文件
这段代码定义了一个名为pubuse.h
的头文件,它在C++编程中用于声明一些全局常量、类型定义和包含必要的库。主要点如下:
-
声明了一些基本的数据类型别名:
Status
: 整型变量,用于表示函数的状态(如成功、错误等)。Boolean
: 整型变量,用于表示布尔值(TRUE或FALSE)。
-
定义了一些预处理器宏:
TRUE
和FALSE
分别代表整数值1和0的符号表示。OK
,ERROR
, 和INFEASIBLE
用作可能的函数返回状态。- 注意
OVERFLOW
宏注释掉,因为与math.h
中的同名宏冲突,这可能会导致潜在问题。
-
包含了常用的C++库,如
iostream
,cctype
,cstdlib
,stdio.h
,math.h
, 和conio.h
。conio.h
通常用于控制台输入输出操作。 -
使用了
std
命名空间,表明程序使用了C++标准库中的功能。 -
代码中使用了C风格库函数,如
malloc()
,atoi()
,eof()
, 和exit()
,以及C++类库函数,如malloc.h
,string
,sstream
和iostream
。
在分析这个文件时,会注意到该头文件可能被用来构建支持二叉树数据结构的操作,比如遍历、插入、删除等。但这个信息没有直接在文件中体现,需要查看相关源代码文件来进一步判断。
#include<string>
#include<ctype.h>
#include<malloc.h> /* malloc()等*/
#include<limits.h> /* INT_MAX 等*/
#include<stdio.h> /* EOF(=^Z 或F6),NULL */
#include<iostream>
#include<stdlib.h> /* atoi() */
#include<io.h> /* eof() */
#include<math.h>/* floor(),ceil(),abs() */
#include<process.h> /* exit() */
#include"conio.h"
#include <sstream>
using namespace std;
/* 函数结果状态代码*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//#define OVERFLOW -2 因为在math. h 中已定义OVERFLOW 的值为3,故去掉此行
typedef int Status; /* Status 是函数的类型,其值是函数结果状态代码,如OK 等*/
typedef int Boolean; /* Boolean 是布尔类型,其值是TRUE 或FALSE */
BiTreeDef.h
文件
BiTreeDef.h
文件定义了一个名为 BiTNode
的结构体,它表示二叉树中的一个节点。
节点包含三个成员:data
用于存储元素,类型为 TElemType
,这是一个只包含单个字符的结构体;lchild
和 rchild
分别是指向左孩子和右孩子的指针。
BiTNode
结构体本身被定义为指针类型 BiTree
。
这是二叉树在 C 语言中的一种基本表示。
#include"pubuse.h"
typedef struct {
char c;
}TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
BinTreeAlgo.h文件
这是一个C++程序,定义了一个名为BiTree
的数据结构,表示二叉树。文件包含了以下函数:
InitBiTree()
:初始化二叉树,将指针置空并返回OK。PreCreateBiTree()
、InCreateBiTree()
和PostCreateBiTree()
:递归地根据用户输入创建二叉树,采用前序、中序和后序遍历方式插入节点。DestroyBiTree()
:销毁二叉树,通过递归删除节点并释放内存。BiTreeEmpty()
:检测二叉树是否为空,如果根节点为NULL则返回true。BiTreeDepth()
:计算给定二叉树的深度。Root()
:计算二叉树的节点总数(就像一棵满二叉树的叶子节点数)。PreOrderTraverse()
、InOrderTraverse()
和PostOrderTraverse()
:分别实现前序、中序和后序遍历,输出二叉树节点。
这个类包含二叉树的构造、操作以及基本属性的获取,主要用于教学或演示二叉树的数据结构特性。
#include "BinTreeDef.h"
//建立空树
Status InitBiTree(BiTree& T) {
T = NULL;
return OK;
}
//创建二叉树
//先序创建
void PreCreateBiTree(BiTree& T) {
char ch;
ch = _getch();
cout << ch;
if (ch == ' ') T = NULL;
else
{
T = new BiTNode;
T->data.c = ch;
PreCreateBiTree(T->lchild);
PreCreateBiTree(T->rchild);
}
}
//中序创建
void InCreateBiTree(BiTree& T) {
char ch;
ch = _getch();
cout << ch;
if (ch == ' ') T = NULL;
else
{
T = new BiTNode;
InCreateBiTree(T->lchild);
T->data.c = ch;
InCreateBiTree(T->rchild);
}
}
//后序创建
void PostCreateBiTree(BiTree& T) {
char ch;
ch = _getch();
cout << ch;
if (ch == ' ') T = NULL;
else
{
T = new BiTNode;
PostCreateBiTree(T->lchild);
PostCreateBiTree(T->rchild);
T->data.c = ch;
}
}
//销毁二叉树
Status DestroyBiTree(BiTree& T) {
if (T) {
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
delete T;
T = NULL;
}
return OK;
}
//判二叉树是否为空
bool BiTreeEmpty(BiTree T) {
return T == NULL;
}
//求二叉树的深度
int BiTreeDepth(BiTree T) {
if (T == NULL) return 0;
else
{
int m = BiTreeDepth(T->lchild);
int n = BiTreeDepth(T->rchild);
if (m > n) return m + 1;
else return n + 1;
}
}
//求二叉树的叶子结点总数
int Root(BiTree T) {
if (T == NULL) return 0;
else return Root(T->lchild) + Root(T->rchild) + 1;
}
//遍历二叉树
//先序遍历
void PreOrderTraverse(BiTree T) {
if (T) {
cout << T->data.c;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
//中序遍历
void InOrderTraverse(BiTree T) {
if (T) {
InOrderTraverse(T->lchild);
cout << T->data.c;
InOrderTraverse(T->rchild);
}
}
//后序序遍历
void PostOrderTraverse(BiTree T) {
if (T) {
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data.c;
}
}
BinTreeUse.cpp
文件
BinTreeUse.cpp
文件是一个C++程序,使用了头文件BinTreeAlgo.h
。该程序实现了一个二叉树的数据结构,并提供了以下几个功能:
-
菜单选择:用户可以通过命令行选择操作,包括插入节点(1)、删除节点(2)、销毁树(3)、检查是否为空(4)、获取树的深度(5)、查找根节点和孩子个数(6)以及遍历(7),以及退出菜单(0)。
-
基本操作:对于第2、3案(节点插入/销毁树)的子选项,用户会选择插入类型(前序、中序或后序)。
-
遍历:在case 6中,用户可以选择先序、中序或后序遍历,并输出节点的顺序。
-
错误处理:在用户输入无效的选择或数字时,会清除输入流并提示重新输入。
整个main函数构成了一个循环,反复询问用户直到选择退出(0)为止。
#include"BinTreeAlgo.h"
void ShowMenu() {
cout << "========= 二叉树的实现及应用 =========" << endl;
cout << "1. 建立空树" << endl;
cout << "2. 创建二叉树" << endl;
cout << "3. 销毁二叉树" << endl;
cout << "4. 判二叉树是否为空" << endl;
cout << "5. 求二叉树的深度" << endl;
cout << "6. 求二叉树的叶子结点总数" << endl;
cout << "7. 遍历二叉树" << endl;
cout << "0. 退出" << endl;
cout << "请输入你的选择:";
}
void Show2() {
cout << "========= 二叉树的创建 =========" << endl;
cout << "创建二叉树时,输入空格“ ”表示创建空树" << endl;
cout << "1. 先序遍历创建二叉树" << endl;
cout << "2. 中序遍历创建二叉树" << endl;
cout << "3. 后序遍历创建二叉树" << endl;
cout << "请输入你的选择:";
}
void Show7() {
cout << "========= 二叉树的遍历 =========" << endl;
cout << "1. 先序遍历" << endl;
cout << "2. 中序遍历" << endl;
cout << "3. 后序遍历" << endl;
cout << "请输入你的选择:";
}
void ExitEnter() {
cout << "-------------------------------" << endl;
system("pause");
system("cls");
}
int main() {
static BiTree T;
TElemType e;
int numF = 7; //菜单选项数量
int choice;
do {
ShowMenu();
cin >> choice;
while (choice < 0 || choice>numF || cin.fail())
{
system("cls");
cin.clear();
cin.ignore();
ShowMenu();
cin >> choice;
}
switch (choice) {
case 1: {
// 建立空树
system("cls");
if (InitBiTree(T)) cout << "创建空树成功" << endl;
else cout << "创建空树失败" << endl;
ExitEnter();
break;
}
case 2: {
// 创建二叉树
system("cls");
Show2();
int cc;
cin >> cc;
while (cc < 0 || cc > 3 || cin.fail())
{
system("cls");
cin.clear();
cin.ignore();
Show2();
cin >> cc;
}
switch (cc) {
case 1: {
system("cls");
cin.ignore();
cin.clear();
cout << "先序创建二叉树--输入字符创建二叉树,创建完成自动退出" << endl;
cout << "开始输入:";
PreCreateBiTree(T);
cout << "|" << endl;
break;
}
case 2: {
system("cls");
cin.ignore();
cin.clear();
cout << "中序创建二叉树--输入字符创建二叉树,创建完成自动退出" << endl;
cout << "开始输入:";
InCreateBiTree(T);
cout << "|" << endl;
break;
}
case 3: {
system("cls");
cin.ignore();
cin.clear();
cout << "后序创建二叉树--输入字符创建二叉树,创建完成自动退出" << endl;
cout << "开始输入:";
PostCreateBiTree(T);
cout << "|" << endl;
break;
}
}
cout << "\n创建二叉树成功" << endl;
ExitEnter();
break;
}
case 3: {
// 销毁二叉树
system("cls");
if (DestroyBiTree(T)) cout << "销毁成功" << endl;
else cout << "销毁失败" << endl;
ExitEnter();
break;
}
case 4: {
// 判二叉树是否为空
system("cls");
if (BiTreeEmpty(T)) cout << "二叉树为空" << endl;
else cout << "二叉树不为空" << endl;
ExitEnter();
break;
}
case 5: {
// 求二叉树的深度
system("cls");
int n = BiTreeDepth(T);
cout << "二叉树的深度为:" << n << endl;
ExitEnter();
break;
}
case 6: {
// 求二叉树的叶子结点总数
system("cls");
int n = Root(T);
cout << "二叉树的叶子结点数为:" << n << endl;
ExitEnter();
break;
}
case 7: {
// 遍历二叉树
system("cls");
Show7();
int cc2;
cin >> cc2;
while (cc2 < 0 || cc2 > 3 || cin.fail())
{
system("cls");
cin.clear();
cin.ignore();
Show7();
cin >> cc2;
}
switch (cc2) {
case 1: {
system("cls");
cout << "先序遍历二叉树" << endl;
cout << "结果为:";
PreOrderTraverse(T);
cout << "|" << endl;
break;
}
case 2: {
system("cls");
cout << "中序遍历二叉树" << endl;
cout << "结果为:";
InOrderTraverse(T);
cout << "|" << endl;
break;
}
case 3: {
system("cls");
cout << "后序遍历二叉树" << endl;
cout << "结果为:";
PostOrderTraverse(T);
cout << "|" << endl;
break;
}
}
cout << "\n遍历二叉树成功" << endl;
ExitEnter();
break;
}
case 0: {
cout << "-------------------------------" << endl;
cout << "感谢使用,再见!" << endl;
break;
}
default:
system("cls");
cout << "输入无效,请重新选择!" << endl;
break;
}
} while (choice != 0);
return 0;
}
结语
希望你能通过本篇博客,更好理解数据结构——二叉树。
最后,使用愉快!