二叉树C++实现数据结构实验
#include <iostream>
#include <string.h>
#include <stack>
#include <queue>
using namespace std;
template<class T>
struct BiNode //二叉数节点
{T data;BiNode<T>* lchild, *rchild;};template<class T> //模板类
class BiTree
{
public:BiTree(); //默认构造函数~BiTree(); //析构函数BiNode<T>* GetRoot(); //返回根节点void PreOrder(BiNode<T>* node); //先序遍历void InOrder(BiNode<T>* node); //中序遍历void PostOrder(BiNode<T>* node); //后序遍历void LevelOrder(BiNode<T>* node); //层次遍历//选做非递归实现void PreOrderNonRec(BiNode<T>* node); //先void InOrderNonRec(BiNode<T>* node); //中void PostOrderNonRec(BiNode<T>* node); //后//选做深度,节点数,叶子节点数,int NodesNum(BiNode<T>* node); //节点数int TreeDepth(BiNode<T>* node); //深度int LeafNum(BiNode<T>* node); //叶子节点数//选做交换子树void SwapChild(BiNode<T>* node); //交换子树private:BiNode<T>* m_root; //获取根节点BiNode<T>* Create(); //创建二叉树
};template<class T>
BiTree<T>::BiTree()
{m_root = new BiNode<T>;m_root = Create();
}template<class T>
BiTree<T>::~BiTree(){}template<class T>
BiNode<T>* BiTree<T>::Create() //1. 按先序序列构造一棵二叉链表表示的二叉树T;
{char ch=getchar();BiNode<T>* pnode;if (ch == ' ')pnode = NULL;else{pnode = new BiNode<T>;pnode->data = ch;pnode->lchild = Create();pnode->rchild = Create();}return pnode;
}template<class T>
BiNode<T>* BiTree<T>::GetRoot()
{return m_root;
}template<class T>
void BiTree<T>::PreOrder(BiNode<T>* node)
{if (!node)return;else{cout << node->data;PreOrder(node->lchild);PreOrder(node->rchild);}
}template<class T>
void BiTree<T>::InOrder(BiNode<T>* node)
{//前后定根,中序定左右if (!node)return;else{InOrder(node->lchild);cout << node->data;InOrder(node->rchild);}}template<class T>
void BiTree<T>::PostOrder(BiNode<T>* node)
{if (!node)return;else{PostOrder(node->lchild);PostOrder(node->rchild);cout << node->data;}}template<class T>
void BiTree<T>::LevelOrder(BiNode<T>* node)
{//层次遍历需要queue来实现,思路://@1初始化queue// if root为空 返回//@2 push(root)//@3 while(queue不为空)// s <-- queue.front()// queue.pop()// 输入s.data// if(s的左子树不空)// s的左子树入队// if(s的右子树不空)// s的右子树入队queue<BiNode<T>*> q;BiNode<T>* s = node;if (!s)return;q.push(s);while (!q.empty()){s = q.front();q.pop();cout << s->data;if (s->lchild)q.push(s->lchild);if (s->rchild)q.push(s->rchild);}
}//先序遍历非递归需要借助stack s来实现,模拟递归调用
//总的循环边界是当前节点不为空或者stack不空,
template<class T>
void BiTree<T>::PreOrderNonRec(BiNode<T>* node)
{stack<BiNode<T>*> s;BiNode<T>* p = node;while (p|| !s.empty()){/*@1.每次找当前的节点的左子节点直到左为空,经过的节点入栈,@2.然后弹出当前节点,搜索一次右节点,如果p为空并且s空则退出否则继续@1*/while (p)//这里执行VL{cout << p->data;//Vs.push(p);//访问过的加入栈p = p->lchild;//L}if (!s.empty())//这里执行R{p = s.top();s.pop();p = p->rchild;//R}}}template<class T>
void BiTree<T>::InOrderNonRec(BiNode<T>* node)
{//@1 在当前节点p非空时候,将p入栈s,p的左子树赋给p,保证左子树都能入栈// p为空时候,也就是左子树最左边访问到了,这时候在栈非空的时候//@2 取栈顶给p,输入p,出栈,这时候最底层的最左边节点访问了,将p的右子树赋给p,重复@1stack<BiNode<T>*> s;BiNode<T>* p = node;while (p|| !s.empty()){while (p)//这里执行L{s.push(p);p = p->lchild;}if (!s.empty())//这里执行VR{p = s.top();cout << p->data;s.pop();p = p->rchild;}}
}template<class T>
void BiTree<T>::PostOrderNonRec(BiNode<T>* node)
{//访问子节点的条件有两种//1.当前节点的左右节点都为空,可以直接访问//2.前一个被访问的节点是当前节点的子节点//这样就需要两个指针,一个指向当前一个指向前一个被访问的节点//然后保证入栈顺序是先右再左,(这里先压右再压左,这样左在上面,就先访问左)if (!node)return;stack<BiNode<T>*> s;s.push(node);BiNode<T>* pre = NULL;BiNode<T>* cur;while (!s.empty()){cur = s.top();if (!cur->lchild&& !cur->rchild ||(pre != NULL) && (pre == cur->lchild || pre == cur->rchild))//上一次访问的是当前节点的左子树{cout << cur->data;s.pop();pre = cur;//pre是前一个被访问的节点}else{if (cur->rchild)s.push(cur->rchild);if (cur->lchild)s.push(cur->lchild);}}}template<class T>
int BiTree<T>::LeafNum(BiNode<T>* node)
{//递归思路:找到叶子节点返回值加一,返回值计数//2种情况//1.节点为空,返回 0,传递回去//2.每当到达叶子节点,返回 1,传递给上一层函数if (!node)return 0;if (!node->lchild&&!node->rchild)return 1;return LeafNum(node->lchild) + LeafNum(node->rchild);
}template<class T>
int BiTree<T>::TreeDepth(BiNode<T>* node)
{/*递归思路:每个节点都有自己的左右子树,每次返回当前节点左右子树长度大的那个1.如果根节点为空,则深度为0,返回0,递归的出口2.否则深度至少为1,然后累加他们左右子树的深度,*/int LChildDep = 1, RChildDep = 1;if (!node)return 0;LChildDep += TreeDepth(node->lchild);//每次返回之前子树的长度RChildDep += TreeDepth(node->rchild);return (LChildDep>RChildDep) ? (LChildDep) : (RChildDep);}template<class T>
int BiTree<T>::NodesNum(BiNode<T>* node)
{//思路,递归遍历所有节点,如果不是空节点的话,递归返回值加1if (!node)return 0;return NodesNum(node->lchild) + NodesNum(node->rchild) + 1;}template<class T>
void BiTree<T>::SwapChild(BiNode<T>* node)
{//思路,交换所有节点的节点,每个节点走一遍if (node){swap(node->lchild, node->rchild);SwapChild(node->lchild);SwapChild(node->rchild);}
}/*样例输入:
ABC DE G F ↙样例输出:
先序建立一棵二叉树,请输入节点的值:ABC DE G F
建立完毕.
先序:ABCDEGF
中序:CBEGDFA
后序:CGEFDBA
层序:ABCDEFG
选做题1:采用非递归算法实现二叉树遍历
先序:ABCDEGF
中序:CBEGDFA
后序:CGEFDBA
选做题2:求二叉树的深度/结点数目/叶结点数目
TreeDepth is 5
NodesNum is 7
LeafNum is 3
选做题3:将二叉树每个结点的左右子树交换位置。
交换完毕.
先序:ABDFEGC
中序:AFDGEBC
后序:FGEDCBA
层序:ABDCFEG
*/int main()
{cout << "先序建立一棵二叉树,请输入节点的值:";BiTree<char> bitree;cout << "建立完毕." << endl;cout << "先序:";bitree.PreOrder(bitree.GetRoot());cout << endl;cout << "中序:";bitree.InOrder(bitree.GetRoot());cout << endl;cout << "后序:";bitree.PostOrder(bitree.GetRoot());cout << endl;cout << "层序:";bitree.LevelOrder(bitree.GetRoot());cout << endl;cout << "选做题1:采用非递归算法实现二叉树遍历" << endl;cout << "先序:";bitree.PreOrderNonRec(bitree.GetRoot());cout << endl;cout << "中序:";bitree.InOrderNonRec(bitree.GetRoot());cout << endl;cout << "后序:";bitree.PostOrderNonRec(bitree.GetRoot());cout << endl;cout << "选做题2:求二叉树的深度/结点数目/叶结点数目" << endl;cout << "深度为 : " << bitree.TreeDepth(bitree.GetRoot()) << endl;cout << "结点数目 : " << bitree.NodesNum(bitree.GetRoot()) << endl;cout << "叶结点数目: " << bitree.LeafNum(bitree.GetRoot()) << endl;cout << "选做题3:将二叉树每个结点的左右子树交换位置。" << endl;bitree.SwapChild(bitree.GetRoot());cout << "交换完毕." << endl;cout << "先序:";bitree.PreOrder(bitree.GetRoot());cout << endl;cout << "中序:";bitree.InOrder(bitree.GetRoot());cout << endl;cout << "后序:";bitree.PostOrder(bitree.GetRoot());cout << endl;cout << "层序:";bitree.LevelOrder(bitree.GetRoot());cout << endl;system("pause");
}
二叉树C++实现数据结构实验相关推荐
- 二叉树的基本操作——数据结构实验报告
一.实验名称:二叉树 二.实验目的 1)熟练掌握二叉树的存储方式的具体实现过程,实现二叉树的基本操作及运算: 2)进一步巩固指针的用法,栈及队列的基本操作,进一步体会递归算法,学会综合应用. 三.实验 ...
- 数据结构 实验三 栈的基本运算
栈的基本运算 任务一: 顺序栈的基本操作 任务描述: 本关任务:实现顺序栈的基本操作,包括栈的初始化.置空栈.进栈.出栈.判栈空.栈的输出(遍历)等. 相关知识: 为了完成本关任务,你需要掌握: - ...
- sdut 2137 数据结构实验之求二叉树后序遍历和层次遍历
数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descr ...
- sdut 3341数据结构实验之二叉树二:遍历二叉树
数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000MS Memory Limit: 65536K Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如 ...
- 数据结构实验之求二叉树后序遍历和层次遍历
数据结构实验之求二叉树后序遍历和层次遍历 Description 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历和层序遍历. Input 输入数据有多组,第一行是一个整数t (t<100 ...
- 数据结构实验二 树和二叉树的实现
广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A) 2019年5月13日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 学号 17061 ...
- 数据结构实验之二叉树五:层序遍历 // oj3344 队列+二叉树 // 先序 --层次
原题链接:oj3344 数据结构实验之二叉树五:层序遍历 Description 已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示空结点).请建立二叉树并求二叉树的层次遍历序列. In ...
- 数据结构实验报告,二叉树的基本操作(C语言)
数据结构实验报告,二叉树的基本操作(C语言) 作者:命运之光 专栏:数据结构 目录 数据结构实验报告,二叉树的基本操作(C语言) 实验六 二叉树的基本操作 一.需求分析 二.概要设计 三.详细设计 四 ...
- 广州大学学生实验报告,数据结构实验,二叉树的操作与实现
广州大学学生实验报告 开课学院及实验室: 计算机科学与工程实验室 418 2022年10月3日 学院 计算机科学与网络工程 年级.专业.班 计科 姓名 Great Macro ...
最新文章
- 李宏毅线性代数笔记6:矩阵的计算
- 阿里巴巴集团CTO王坚:互联网、数据和计算
- 不断学习UI框架的写法
- Unity图片优化神器 - dither算法究极进化方案
- 音频开发中常见的四个错误
- 1 redux初探、用react开发数值增值案例
- 桌面显示激活windows_愚蠢的怪胎技巧:如何在桌面上显示Windows版本
- 二维数组各行分别求和_【PyTorch入门】之十分钟看懂二维卷积层的运算、实现及应用...
- netbeans7.4_NetBeans 7.4的本机Java打包
- 【目标定位】基于matlab粒子滤波目标定位仿真【含Matlab源码 129期】
- matlab多项式运算开方,matlab多项式运算【技术材料】
- 坦克大战小游戏的实现
- thinkphp6+vue前后端分离开发验证码总是验证不正确问题
- android开发日记 ——avata项目
- Docker 快速入门学习
- 7.2 IDEA 没有Java EE
- 跨国企业在中国 | 麦德龙中国正式引进高品质法国牛肉;雀巢加码在华宠物护理业务...
- git提交如何忽略某些文件
- icpc2018南京站B题 tournament
- 对 Error-State Kalman Filter 的理解
热门文章
- •Oracle 9i企业版官方下载 9.2.0.1.0
- LeetCode 344.Reverse String
- 基于51单片机的多功能智能语音循迹避障小车
- 程序员面试笔试宝典学习记录(一)(常见面试笔试题目)
- CentOS7 安装 RabbitMQ 3.6(方法适用于安装任意版本 RabbitMQ)
- 什么是seo优化?网站seo如何优化
- 一个啥都不懂但还不知天高地厚的我
- cmd无法加载命令解决方法
- 苹果cms模板_苹果cms10好看的模板有那些?
- 计算机之父阿兰·图灵传奇的一生