二叉树的创建与前序、中序和后序的递归与非递归调用

来源:互联网 发布:软件删不掉怎么办 编辑:程序博客网 时间:2024/06/06 02:12
#include<iostream>#include<string>#include<vector>#include<stack>using namespace std;typedef char ElemType;class BiTNode{friend class BiTree;private:ElemType data;BiTNode *lchild,*rchild; //左右孩子指针};class BiTree:public BiTNode{public:void InputBiTNode();//输入构成数的结点元素,‘#’表示空串void Pre_CreateBiTree(BiTNode *&T);//先序构造二叉树void visit(ElemType e);//visit函数用于输出结点元素void PreOrderTraverse(BiTNode *T);//先序遍历二叉树T(递归方式)void InOrderTraverse(BiTNode *T);//中序遍历二叉树T(递归方式)void PostOrderTraverse(BiTNode *T);//后序遍历二叉树T(递归方式)void Iterator_PreOrderTraverse(BiTNode *T);//先序遍历二叉树T(非递归方式)void Iterator_InOrderTraverse(BiTNode *T);//中序遍历二叉树T(非方递归式)void Iterator_PostOrderTraverse(BiTNode *T);//后序遍历二叉树T(非递归方式)void Iterator_PreOrderTraverse2(BiTNode *T);//先序遍历二叉树T(非递归方式2)void Iterator_InOrderTraverse2(BiTNode *T);//中序遍历二叉树T(非方递归式2)void Iterator_PostOrderTraverse2(BiTNode *T);//后序遍历二叉树T(非递归方式2)private:vector<ElemType> elem;};void BiTree::InputBiTNode(){ElemType ch;cout<<"!!!注意:(1)'#'表示空结点;(2)请在输入的字符串末尾加0,作为输入结束的标志。"<<endl;while(cin>>ch&&ch!='0'){elem.push_back(ch);//在容器中加入结点元素}//while}//InputBiBodevoid BiTree::Pre_CreateBiTree(BiTNode *&T){                             vector<ElemType>::iterator it=elem.begin();//迭代器it指向elem的开头if(it!=elem.end()){if(*it=='#')//字符为空格,表示结点不存在{T=NULL;elem.erase(it);//删除迭代器it指向的elem中的元素,作用是依次删除elem的第一个元素}//ifelse{if(!(T=new BiTNode))exit(-1);T->data=*it;//生成根结点elem.erase(it);//删除迭代器it指向的elem中的元素,作用是依次删除elem的第一个元素Pre_CreateBiTree(T->lchild);    //构造左子树Pre_CreateBiTree(T->rchild);//构造右子树}//else}//ifelse//此时elem为空,使此时T=NULL;,即结束最初的T的结点的赋值T=NULL;}//Pre_CreateBiTreevoid BiTree::PreOrderTraverse(BiTNode *T){if(T)//二叉树存在{visit(T->data);//访问根结点PreOrderTraverse(T->lchild);//先序遍历左子树PreOrderTraverse(T->rchild);//先序遍历右子树}//if}//PreOrderTraversevoid BiTree::InOrderTraverse(BiTNode *T){if(T){InOrderTraverse(T->lchild);//中序遍历左子树visit(T->data);//访问根结点InOrderTraverse(T->rchild);//中序遍历右子树}//if}//InOrderTraversevoid BiTree::PostOrderTraverse(BiTNode *T){if(T){PostOrderTraverse(T->lchild);//后序遍历左子树PostOrderTraverse(T->rchild);//后序遍历右子树visit(T->data);//访问根结点}//if}//PostOrderTraversevoid BiTree::Iterator_PreOrderTraverse(BiTNode *T){stack<BiTNode*> S;//用来存储树结点的BiTNode *q;S.push(T);//根指针入栈while(!S.empty()){while((q=S.top())&&q)//先访问结点,再将结点的左子树入栈,栈顶为空指针结束{visit(q->data);S.push(q->lchild);}//whileS.pop();//空指针出栈if(!S.empty())//由于结点元素已被访问,因此此处只需删除结点,将结点的右结点入栈{q=S.top();S.pop();//访问结点时将其从栈中删除S.push(q->rchild);}//if}//while}//Iterator_PreOrderTraversevoid BiTree::Iterator_InOrderTraverse(BiTNode *T){stack<BiTNode*> S;//用来存储树结点的BiTNode *q;S.push(T);//根指针入栈while(!S.empty()){while((q=S.top())&&q)//向左走到尽头{S.push(q->lchild);}//whileS.pop();//空指针出栈if(!S.empty())//访问结点,将结点的右结点入栈{q=S.top();S.pop();//访问结点时将其从栈中删除visit(q->data);S.push(q->rchild);//将右结点入栈}//if}//while}//Iterator_InOrderTraversevoid BiTree::Iterator_PostOrderTraverse(BiTNode *T){stack<BiTNode*> S;//用来存储树结点的BiTNode *q,*point=T;S.push(T);//根指针入栈while(!S.empty()){while((q=S.top())&&q)//向左走到尽头{S.push(q->lchild);}//whileS.pop();//空指针出栈if(!S.empty()){q=S.top();S.push(q->rchild);//右结点入栈if(S.top()==NULL)//入栈的右结点为空{S.pop();//空指针出栈point=S.top();S.pop();//访问根结点并出栈visit(point->data);while((!S.empty())&&(S.top()->rchild==point))//栈顶结点的右结点是刚被访问的结点{point=S.top();S.pop();//由于该结点的右结点已经被访问,说明完成了左右子树的遍历visit(point->data);//该结点作为子树的根结点则被出栈访问 }//whileif(!S.empty()){q=S.top();//此时栈顶结点的右结点还未入栈S.push(q->rchild);//右结点入栈}//if}//if}//if}//while}//Iterator_PostOrderTraversevoid BiTree::Iterator_PreOrderTraverse2(BiTNode *T){stack<BiTNode*> S;//用来存储树结点的BiTNode *q=T;while(q||(!S.empty())){if(q){visit(q->data);//访问根结点S.push(q);q=q->lchild;//遍历左子树}//ifelse{q=S.top();S.pop();//采用先序遍历,结点入栈时已被访问,因此出栈时无需访问q=q->rchild;}//else}//while}//Iterator_PreOrderTraverse2void BiTree::Iterator_InOrderTraverse2(BiTNode *T){stack<BiTNode*> S;//用来存储树结点的BiTNode *q=T;while(q||(!S.empty())){if(q)//结点存在{S.push(q);//根指针进栈,遍历左子树,q=q->lchild;}//ifelse//根指针退栈,访问根结点{q=S.top();S.pop();visit(q->data);q=q->rchild;//遍历右子树}//else}//while}//Iterator_InOrderTraverse2void BiTree::Iterator_PostOrderTraverse2(BiTNode *T){stack<BiTNode*> S;//用来存储树结点的BiTNode *q=T,*point=T;while(q||(!S.empty())){if(q){S.push(q);//根指针进栈,遍历左子树q=q->lchild;}//ifelse{q=S.top();q=q->rchild;//遍历右子树if(!q)//将要入栈的右子树为空{point=S.top();S.pop();//在遍历完左右子树后访问根结点visit(point->data);while((!S.empty())&&(S.top()->rchild==point))//栈顶结点的右结点是刚被访问的结点{point=S.top();S.pop();//由于该结点的右结点已经被访问,说明完成了左右子树的遍历visit(point->data);//该结点作为子树的根结点则被出栈访问 }//whileif(!S.empty()){q=S.top();//此时栈顶结点的右结点还未入栈q=q->rchild;//右结点入栈}//if}//if}//else}//while}//Iterator_PostOrderTraverse2void BiTree::visit(ElemType e){cout<<e;}//visitvoid main(){BiTree BT;BiTNode *T;BT.InputBiTNode();BT.Pre_CreateBiTree(T);cout<<"\n"<<"先序遍历(递归)二叉树T:"<<endl;BT.PreOrderTraverse(T);cout<<endl;cout<<"先序遍历(非递归)二叉树T:"<<endl;BT.Iterator_PreOrderTraverse(T);cout<<endl;cout<<"先序遍历(非递归2)二叉树T:"<<endl;BT.Iterator_PreOrderTraverse2(T);cout<<endl;cout<<"\n"<<"中序遍历(递归)二叉树T:"<<endl;BT.InOrderTraverse(T);cout<<endl;cout<<"中序遍历(非递归)二叉树T:"<<endl;BT.Iterator_InOrderTraverse(T);cout<<endl;cout<<"中序遍历(非递归2)二叉树T:"<<endl;BT.Iterator_InOrderTraverse2(T);cout<<endl;cout<<"\n"<<"后序遍历(递归)二叉树T:"<<endl;BT.PostOrderTraverse(T);cout<<endl;cout<<"后序遍历(非递归)二叉树T:"<<endl;BT.Iterator_PostOrderTraverse(T);cout<<endl;cout<<"后序遍历(非递归2)二叉树T:"<<endl;BT.Iterator_PostOrderTraverse2(T);cout<<endl;}//main

以下图所示二叉树为例,对中序(非递归)和后序(非递归2)算法栈的入栈和出栈情况进行简单说明:




0 0
原创粉丝点击