《数据结构》课程设计 —— 二叉树的实现(C++)

目录

二叉树的实现

项目获取

具体实现解析

pubuse.h的头文件

BiTreeDef.h 文件

BinTreeAlgo.h文件

BinTreeUse.cpp 文件

结语


二叉树的实现

文件名功能简介
BinTreeAlgo.h定义二叉树操作接口(初始化,遍历,插入,删除等)以及其辅助函数
BinTreeDef.h定义二叉树节点结构(数据、左右孩子)和二叉树公共类型
pubuse.h通用头文件,包含全局定义(全局变量、预处理器宏、函数库等)
BinTreeUse.cpp用户界面实现,提供图形化菜单操作与二叉树的基本操作(如创建、删除、查询与遍历)

总结:程序整体功能是,通过用户交互式操作,实现对二叉树结构的创建、管理(插入、删除),并能展示其遍历结果,旨在演示和学习二叉树数据结构的典型应用。

这个项目包含一组C++文件,包括定义二叉树结构、接口和操作函数的头文件(BinTreeAlgo.h, BinTreeDef.h),全局公共使用的头文件(pubuse.h),以及利用这些结构进行用户交互操作的实现代码(BinTreeUse.cpp),整体上实现了二叉树数据结构的基础操作演示。

项目获取

【免费】学生课程实验,C++数据结构实验,二叉树的实现,vs2022完整项目,包含完整代码,开箱即用资源-CSDN文库icon-default.png?t=N7T8https://download.csdn.net/download/btaworld/89291999?spm=1003.2166.3001.6637.3

所有代码已经上传到CSDN,通过资源绑定功能已经绑定本篇博客,有需要请自取,完整的VS2022项目,运行“数据结构-二叉树.sln”即可在vs2022中打开(一般来说,版本无限制)

在我上传时,设置了0积分,可以免费获取,但不保证后续积分要求会不会变化(但放心,不会变成付费或会员专享资源),不过,还请尽快保存! 

具体实现解析

pubuse.h的头文件

这段代码定义了一个名为pubuse.h的头文件,它在C++编程中用于声明一些全局常量、类型定义和包含必要的库。主要点如下:

  1. 声明了一些基本的数据类型别名:

    • Status: 整型变量,用于表示函数的状态(如成功、错误等)。
    • Boolean: 整型变量,用于表示布尔值(TRUE或FALSE)。
  2. 定义了一些预处理器宏:

    • TRUE 和 FALSE 分别代表整数值1和0的符号表示。
    • OKERROR, 和 INFEASIBLE 用作可能的函数返回状态。
    • 注意OVERFLOW宏注释掉,因为与math.h中的同名宏冲突,这可能会导致潜在问题。
  3. 包含了常用的C++库,如iostreamcctypecstdlibstdio.hmath.h, 和conio.hconio.h通常用于控制台输入输出操作。

  4. 使用了std命名空间,表明程序使用了C++标准库中的功能。

  5. 代码中使用了C风格库函数,如malloc()atoi()eof(), 和exit(),以及C++类库函数,如malloc.hstringsstream 和 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的数据结构,表示二叉树。文件包含了以下函数:

  1. InitBiTree():初始化二叉树,将指针置空并返回OK。
  2. PreCreateBiTree()InCreateBiTree()PostCreateBiTree():递归地根据用户输入创建二叉树,采用前序、中序和后序遍历方式插入节点。
  3. DestroyBiTree():销毁二叉树,通过递归删除节点并释放内存。
  4. BiTreeEmpty():检测二叉树是否为空,如果根节点为NULL则返回true。
  5. BiTreeDepth():计算给定二叉树的深度。
  6. Root():计算二叉树的节点总数(就像一棵满二叉树的叶子节点数)。
  7. 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. 菜单选择:用户可以通过命令行选择操作,包括插入节点(1)、删除节点(2)、销毁树(3)、检查是否为空(4)、获取树的深度(5)、查找根节点和孩子个数(6)以及遍历(7),以及退出菜单(0)。

  2. 基本操作:对于第2、3案(节点插入/销毁树)的子选项,用户会选择插入类型(前序、中序或后序)。

  3. 遍历:在case 6中,用户可以选择先序、中序或后序遍历,并输出节点的顺序。

  4. 错误处理:在用户输入无效的选择或数字时,会清除输入流并提示重新输入。

整个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;
}

结语

希望你能通过本篇博客,更好理解数据结构——二叉树。

最后,使用愉快!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值