#ifndef _BITREE_H 
#define   _BITREE_H 
#include "Stack.h"

#include "Queue.h"
template <class DataType>
class BiTree;                                      //友元类引用申明

template <class DataType>
class TreeNode
{
TreeNode():lchild(NULL),rchild(NULL){}
friend class BiTree<DataType>;
private:
DataType data;
TreeNode *lchild,*rchild;
//bool tag;                                     //后序遍历时用的标志域
};

template <class DataType>
class BiTree{
public:
void CreateBiTree();                            //创建根节点------主过程
void CreateBiTree(TreeNode<DataType>* &p);      //创建节点函数----子过程
void PreROrderTraverse();                       //递归------先序遍历二叉树---主过程              
void PreROrderTraverse(TreeNode<DataType>* p);  //递归------先序遍历二叉树---子过程
void InROrderTraverse();                        //递归------中序遍历二叉树---主过程
void InROrderTraverse(TreeNode<DataType>* p);   //递归------中序遍历二叉树---子过程
void PosROrderTraverse();                       //递归------后序遍历二叉树---主过程
void PosROrderTraverse(TreeNode<DataType>* p);  //递归------后序遍历二叉树---子过程
void PreOrderTraverse();                        //非递归------中序遍历二叉树
void InOrderTraverse();                         //非递归------中序遍历二叉树
void PosOrderTraverse();                        //非递归------后序遍历二叉树
void LevelOrderTraverse();                      //非递归------层次遍历二叉树
protected:
TreeNode<DataType>* root;                       //树根
DataType temp;                                  //代表元素为空的符号
};

template <class DataType>
void BiTree<DataType>::CreateBiTree()
{
cout<<"请输入代表元素为空的符号:";
cin>>temp;   //若换输入方式,以上三句可以去掉
if(!(root=(TreeNode<DataType>*)malloc(sizeof(TreeNode<DataType>)))) exit(1);
cout<<"请输入数据:"<<endl;
CreateBiTree(root);
}

template <class DataType>
void BiTree<DataType>::CreateBiTree(TreeNode<DataType>* &p)
{
TreeNode<DataType>* px;
if(!(px=(TreeNode<DataType>*)malloc(sizeof(TreeNode<DataType>)))) exit(1);
cin>>px->data;
if(px->data==temp) {p=NULL;free(px);}
else{
p=px;
// p->tag=false;                                   //后序遍历时用的标志域初始化
CreateBiTree(px->lchild);
CreateBiTree(px->rchild);
}
}

template <class DataType>
void BiTree<DataType>::PreROrderTraverse()
{
PreROrderTraverse(root);
}

template <class DataType>
void BiTree<DataType>::PreROrderTraverse(TreeNode<DataType>* p)
{
if(p){
   cout<<p->data<<" ";
   PreROrderTraverse(p->lchild);
   PreROrderTraverse(p->rchild);
}
}

template <class DataType>
void BiTree<DataType>::InROrderTraverse()
{
InROrderTraverse(root);
}

template <class DataType>
void BiTree<DataType>::InROrderTraverse(TreeNode<DataType>* p)
{
if(p){
   InROrderTraverse(p->lchild);
   cout<<p->data<<" ";
   InROrderTraverse(p->rchild);
}
}

template <class DataType>
void BiTree<DataType>::PosROrderTraverse()
{
PosROrderTraverse(root);
}

template <class DataType>
void BiTree<DataType>::PosROrderTraverse(TreeNode<DataType>* p)
{
if(p){
   PosROrderTraverse(p->lchild);
   PosROrderTraverse(p->rchild);
   cout<<p->data<<" ";
}
}

template <class DataType>
void BiTree<DataType>::PreOrderTraverse()
{
Stack<TreeNode<DataType>*> S;
TreeNode<DataType>* p;
p=root;
while(p||!S.StackEmpty()){
  if(p){S.Push(p);cout<<p->data<<" "; p=p->lchild;}
  else{
    S.Pop(p);
    p=p->rchild;
   }
}
S.DestroyStack();
}

template <class DataType>
void BiTree<DataType>::InOrderTraverse()
{
Stack<TreeNode<DataType>*> S;
TreeNode<DataType>* p;
p=root;
while(p||!S.StackEmpty()){
  if(p){S.Push(p); p=p->lchild;}
  else{
    S.Pop(p);
    cout<<p->data<<" ";
    p=p->rchild;
   }
}
S.DestroyStack();
}

template <class DataType>
void BiTree<DataType>::PosOrderTraverse()
{
Stack<TreeNode<DataType>*> S;
TreeNode<DataType>* p;
TreeNode<DataType>* r;       //使用r节点表示访问了右子树替代标志域
p=root;
while(p||!S.StackEmpty())
{
  if(p){S.Push(p);p=p->lchild;}
  else{
    S.GetTop(p);
   if(p->rchild&&p->rchild!=r){p=p->rchild;S.Push(p);p=p->lchild;}
   else{S.Pop(p);cout<<p->data<<" ";r=p;p=NULL;}
   }
}
S.DestroyStack();
}

//template <class DataType>
//void BiTree<DataType>::PosOrderTraverse()
//{
// Stack<TreeNode<DataType>*> S;
// TreeNode<DataType>* p;
// p=root;
// while(p||!S.StackEmpty())
// {
//   if(p){S.Push(p); p->tag=true;p=p->lchild;}
//   else{
//    S.GetTop(p);
//    if(p->rchild&&!p->rchild->tag){  
//      p=p->rchild;S.Push(p);p->tag=true;p=p->lchild;
//    }
//    else{S.Pop(p);cout<<p->data<<" ";p=NULL;}
//   }
// }
//   S.DestroyStack();
//}

template <class DataType>
void BiTree<DataType>::LevelOrderTraverse()
{
Queue<TreeNode<DataType>*> qu;
TreeNode<DataType>* p;
qu.EnQueue(root);
while(!qu.QueueEmpty()){
   qu.DeQueue(p);
   cout<<p->data<<" ";
  if (p->lchild!= NULL) qu.EnQueue(p->lchild);
        if (p->rchild!= NULL) qu.EnQueue(p->rchild);
}

#endif

#include<iostream>
using namespace std; 
#include "BiTree.h"
int main(void)
{
BiTree<char> my;
my.CreateBiTree();
my.PreROrderTraverse();
cout<<endl;
my.PreOrderTraverse();
cout<<endl;
my.InOrderTraverse();
cout<<endl;
my.InROrderTraverse();
cout<<endl;
my.PosROrderTraverse();
cout<<endl;
my.PosOrderTraverse();

cout<<endl;
my.LevelOrderTraverse();
return 0;
}

二叉树(前中后序递归非递归遍历,层次遍历相关推荐

  1. 二叉树前中后序遍历以及节点计算

    二叉树前中后序遍历以及节点计算 二叉树 分类 二叉链的数据结构 三叉链的数据结构 四种遍历方法 深度优先遍历:前中后序 广度优先遍历:层序遍历 计算 节点个数 叶子节点个数 树的高度 第k层的节点个数 ...

  2. 二叉树前中后序遍历的非递归实现以及层次遍历、zig-zag型遍历详解

    前言 二叉树的遍历是一个比较常见的问题,递归实现二叉树的前中后序遍历比较简单,但非递归实现二叉树的前中后序遍历相对有难度.这篇博客将详述如何使用非递归的方式实现二叉树的前中后序遍历,在进行理论描述的同 ...

  3. 二叉树前中后序遍历+刷题【中】【数据结构/初阶/C语言实现】

    文章目录 1. 二叉树基础操作 1.1 二叉树遍历 1.1.1 前序遍历 前序遍历(Pre-Order Traversal) 1.1.2 中序遍历 中序遍历(In-Order Traversal) 1 ...

  4. 【霍罗维兹数据结构】二叉树前中后序遍历 | 层序遍历 | 复制二叉树 | 判断两个二叉树全等 | 可满足性问题

    写在前面 学习二叉树结构,最简单的方式就是遍历.所谓二叉树遍历,就是按照某种特定的规则,一次对二叉树中的节点进行相应的操作,并且每个节点只操作一次. 访问节点所做的操作要看具体的应用问题.遍历是二叉树 ...

  5. 线索二叉树(前中后序线索化/遍历/画线索)

    线索二叉树 文章目录 线索二叉树 1 线索二叉树的基本概念 2 线索二叉树的构造 2.1 线索二叉树的存储结构 2.2 给线索二叉树画线索 2.2.1 中序 2.2.2 先序 2.2.3 后序 2.3 ...

  6. LeetCode——树:层次遍历、前中后序遍历

    LeetCode--树:层次遍历.前中后序遍历 目录 层次遍历 二叉树的层平均值 找树左下角的值 前中后序遍历 概述 非递归实现二叉树的前序遍历 非递归实现二叉树的中序遍历 非递归实现二叉树的后序遍历 ...

  7. 二叉树非递归dfs——简单思路搞定前中后序遍历

    前言:相信很多同学都被二叉树非递归dfs的前中后序遍历方法弄的头疼.网上的答案,什么前中后序遍历各有一套写法,还有什么一个栈的写法,两个栈的写法.看起来能理解,一闭眼自己写都记不住.今天介绍一种用一种 ...

  8. python实现二叉树非递归前中后序遍历

    python实现二叉树非递归前中后层序遍历 二叉树是数据结构中重要的一部分,本文简单介绍用python实现二叉树的前中后序遍历,包括递归和非递归思路算法. # -*- 二叉树 begin -*- # ...

  9. 二叉树N叉数的前中后序遍历总结,python实现递归法和迭代法

    关于二叉树的前序遍历(preoder).中序遍历(inorder)和后序遍历(postorder),实际上只需要记住:左子节点一定在右子节点的左边(左右),所谓前中后序遍历就是根节点的位置不同,前序是 ...

  10. [Leedcode][JAVA][第94/144/145题][前中后序遍历][递归][迭代][二叉树]

    [问题描述][] 前序遍历 先输出当前结点的数据,再依次遍历输出左结点和右结点 中序遍历 先遍历输出左结点,再输出当前结点的数据,再遍历输出右结点 后续遍历 先遍历输出左结点,再遍历输出右结点,最后输 ...

最新文章

  1. solr的安装配置与helloworld
  2. 在Linux上安装PostgreSQL
  3. DB2 SQL性能调优秘笈pdf
  4. 线程之售票系统pthread_mutex,_lock,_unlock
  5. java 析构函数_《JAVA编程思想》5分钟速成:第5章(初始化和清理)
  6. Linux中的mate程序的进程,终端下以后台模式运行Linux程序的过程详解
  7. 微信小程序系列(5)如何用微信小程序写一个论坛?贴心代码详解(三)列表页
  8. 如何调用TUIO中的源码
  9. 在C#中如何将多个rtf文件内容组合在一起用一个rtf文件保存?
  10. 新榜微信文章抓取客户端(APSpider)
  11. 在线多功能工具箱php源码
  12. 加速打开win10自带图片查看器
  13. ZooKeeper性能测试
  14. MySQL查年龄18到22的信息_Mysql查询SQL相关总结(根据生日以及身份证查询年龄以及性别区域等)...
  15. 人类700万年(震撼的极简人类史)
  16. 测试模板:Showcase规范和流程
  17. 服务器的mysql目录在哪,oracle数据库目录在哪
  18. Reliability, Availability, Serviceability (RAS) 介绍
  19. Mysql中语言分类和区别
  20. 一个简单的例子解释什么是量子计算机

热门文章

  1. win11文件夹打开延迟怎么办 Windows11文件打开延迟的解决方法
  2. ActiveMQ代码示例
  3. Define a New Server 没有tomcat选项
  4. 麦克纳姆轮全向移动机器人的特性
  5. 将vue项目打包部署到云服务器(傻瓜式宝塔面板)
  6. 洛谷——P1554 梦中的统计
  7. python之计算空间向量夹角
  8. js中的内置对象(详细篇)
  9. Widows下TortoiseGit登录密码错误
  10. 清除vlan.dat文件