二叉树的递归与非递归算法(前中后序遍历,C++实现)

/*//
// 名    称 (Unit Name):    BiTree.h 二叉树头文件
// 作    者 (  Author ):    Hector(张伟)
// 邮    箱 (  E-mail ):    ourys@qq.com
// 支    持 ( Support ):    http://ourys.com          
// 备    注 ( Remarks ): 包含文件栈的地址:http://ourys.com/post/38.html
//*/
#ifndef _BITREE_H
#define  _BITREE_H
#include "Stack.h"
template <class DataType>
class BiTree;                                      //友元类引用申明
/*--------  树的节点定义,将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();
}

/*--------非递归------后序遍历二叉树(运用标志域,使用时请将有关tag的注释取消掉)--------------*/
//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()
{}
#endif

/*----------------   http://ourys.com原创,做人要厚道,转帖请标明来处    ------- Author:Hector -------*/

/*----------------  基本测试文件  -------*/

#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();
 return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值