#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. 二叉树的基本操作——数据结构实验报告

    一.实验名称:二叉树 二.实验目的 1)熟练掌握二叉树的存储方式的具体实现过程,实现二叉树的基本操作及运算: 2)进一步巩固指针的用法,栈及队列的基本操作,进一步体会递归算法,学会综合应用. 三.实验 ...

  2. 数据结构 实验三 栈的基本运算

    栈的基本运算 任务一: 顺序栈的基本操作 任务描述: 本关任务:实现顺序栈的基本操作,包括栈的初始化.置空栈.进栈.出栈.判栈空.栈的输出(遍历)等. 相关知识: 为了完成本关任务,你需要掌握: - ...

  3. sdut 2137 数据结构实验之求二叉树后序遍历和层次遍历

    数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descr ...

  4. sdut 3341数据结构实验之二叉树二:遍历二叉树

    数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000MS Memory Limit: 65536K Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如 ...

  5. 数据结构实验之求二叉树后序遍历和层次遍历

    数据结构实验之求二叉树后序遍历和层次遍历 Description 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历和层序遍历. Input 输入数据有多组,第一行是一个整数t (t<100 ...

  6. 数据结构实验二 树和二叉树的实现

    广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A)     2019年5月13日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 学号 17061 ...

  7. 数据结构实验之二叉树五:层序遍历 // oj3344 队列+二叉树 // 先序 --层次

    原题链接:oj3344 数据结构实验之二叉树五:层序遍历 Description 已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示空结点).请建立二叉树并求二叉树的层次遍历序列. In ...

  8. 数据结构实验报告,二叉树的基本操作(C语言)

    数据结构实验报告,二叉树的基本操作(C语言) 作者:命运之光 专栏:数据结构 目录 数据结构实验报告,二叉树的基本操作(C语言) 实验六 二叉树的基本操作 一.需求分析 二.概要设计 三.详细设计 四 ...

  9. 广州大学学生实验报告,数据结构实验,二叉树的操作与实现

    广州大学学生实验报告 开课学院及实验室: 计算机科学与工程实验室 418              2022年10月3日 学院 计算机科学与网络工程 年级.专业.班 计科 姓名 Great Macro ...

最新文章

  1. 李宏毅线性代数笔记6:矩阵的计算
  2. 阿里巴巴集团CTO王坚:互联网、数据和计算
  3. 不断学习UI框架的写法
  4. Unity图片优化神器 - dither算法究极进化方案
  5. 音频开发中常见的四个错误
  6. 1 redux初探、用react开发数值增值案例
  7. 桌面显示激活windows_愚蠢的怪胎技巧:如何在桌面上显示Windows版本
  8. 二维数组各行分别求和_【PyTorch入门】之十分钟看懂二维卷积层的运算、实现及应用...
  9. netbeans7.4_NetBeans 7.4的本机Java打包
  10. 【目标定位】基于matlab粒子滤波目标定位仿真【含Matlab源码 129期】
  11. matlab多项式运算开方,matlab多项式运算【技术材料】
  12. 坦克大战小游戏的实现
  13. thinkphp6+vue前后端分离开发验证码总是验证不正确问题
  14. android开发日记 ——avata项目
  15. Docker 快速入门学习
  16. 7.2 IDEA 没有Java EE
  17. 跨国企业在中国 | 麦德龙中国正式引进高品质法国牛肉;雀巢加码在华宠物护理业务...
  18. git提交如何忽略某些文件
  19. icpc2018南京站B题 tournament
  20. 对 Error-State Kalman Filter 的理解

热门文章

  1. •Oracle 9i企业版官方下载 9.2.0.1.0
  2. LeetCode 344.Reverse String
  3. 基于51单片机的多功能智能语音循迹避障小车
  4. 程序员面试笔试宝典学习记录(一)(常见面试笔试题目)
  5. CentOS7 安装 RabbitMQ 3.6(方法适用于安装任意版本 RabbitMQ)
  6. 什么是seo优化?网站seo如何优化
  7. 一个啥都不懂但还不知天高地厚的我
  8. cmd无法加载命令解决方法
  9. 苹果cms模板_苹果cms10好看的模板有那些?
  10. 计算机之父阿兰·图灵传奇的一生