/*************************************************************/ /* 三、二叉树的遍历 /* 1.输入一个完全二叉树的层次遍历字符串,创建这个二叉树, /* 输出这个二叉树的前序遍历字符串、中序遍历字符串、 /* 后序遍历字符串、结点数目、二叉树高度。 /* 2.输入二叉树前序序列和中序序列(各元素各不相同), /* 创建这个二叉树,输出该二叉树的后序序列。 /*************************************************************/ //链表描述二叉树的创建与遍历 #include <iostream> #include <string> #include <queue> #include <stack> using namespace std; using std::queue; using std::stack; #define MAX 100 //前中序输入的最大数目 static string outputString=""; /**********************************/ /*以下内容是一个二叉树数据结构定义*/ /**********************************/ template<class T> class BinaryTreeNode { public: BinaryTreeNode(){LeftChild=RightChild=0;} BinaryTreeNode(const T&e){data=e;LeftChild=RightChild=0;} BinaryTreeNode(const T&e,BinaryTreeNode *l,BinaryTreeNode *r){data=e;LeftChild=l;RightChild=r;} T data; BinaryTreeNode<T>*LeftChild; //左子树 BinaryTreeNode<T>*RightChild; //右子树 }; /**********************************/ /*以下内容是一个二叉树临时元素定义*/ /**********************************/ #ifndef STACKELEMENT_H #define STACKELEMENT_H //StackElement结构的定义是为了解决非递归后序遍历问题 enum Tags{Left,Right}; template<class T> struct StackElement{ BinaryTreeNode<T>* pointer; Tags tag; }; #endif template<class T> class BinaryTree { public: BinaryTree(){root=0;} ~BinaryTree(){}; bool IsEmpty()const{return ((root)?false:true)}; //如果root存在则为false,也就是不为空。 bool Root(T&x)const; void MakeTree(const T&element,BinaryTree<T>&left,BinaryTree<T>&right); void MakeTree(BinaryTreeNode<T>*r){root=r;} void BreakTree(T&element,BinaryTree<T>&left,BinaryTree<T>&right); void PreOrder(void(*Visit)(BinaryTreeNode<T>*u)){PreOrder(Visit,root);} void InOrder(void(*Visit)(BinaryTreeNode<T>*u)){InOrder(Visit,root);} void PostOrder(void(*Visit)(BinaryTreeNode<T>*u)){PostOrder(Visit,root);} void LevelOrder(void(*Visit)(BinaryTreeNode<T>*u)){LevelOrder(Visit,root);}; //二叉树类的扩充 void PreOutput(); void InOutput(); void PostOutput(); void LevelOutput(); void Delete(); //删除二叉树并释放其节点 void AddNode(const T&u); //删除二叉树并释放其节点 int Height(BinaryTreeNode<T>*t)const; //返回树的高度 int Size(); //返回树中的节点数 BinaryTreeNode<T>*root; void PreOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); void InOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); void PostOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); void LevelOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); }; //取根节点的data域 //如果没有根节点则返回false template<class T> bool BinaryTree<T>::Root(T&x)const { if(root) { x=root->data; return true; } else { return false; } } //将left,right,element合并成一颗新树 //left、right和this必须是不同的树 template<class T> void BinaryTree<T>::MakeTree(const T&element,BinaryTree<T>&left,BinaryTree<T>&right) { root = new BinaryTreeNode<T>(element,left.root,right.root); left.root=right.root=0; //禁止通过其他途径访问left和right } void BadInput(){ cout<<"Bad Input!"<<endl; } //将this拆分成left、right和element //left、right和this必须是不同的树 template<class T> void BinaryTree<T>::BreakTree(T&element,BinaryTree<T>&left,BinaryTree<T>&right) { if(root) throw BadInput();//空树 //分解树 element=root->data; left.root=root->LeftChild; right.root=root->RightChild; delete root; root = 0; } //静态成员函数Output输出树 template<class T> static void Output(BinaryTreeNode<T>*t) { outputString+=t->data; outputString+=","; } template<class T> void BinaryTree<T>::PreOutput() { outputString=""; PreOrder(Output,root); outputString.erase(outputString.end()-1); cout<<outputString<<endl; } template<class T> void BinaryTree<T>::InOutput() { outputString=""; InOrder(Output,root); outputString.erase(outputString.end()-1); cout<<outputString<<endl; } template<class T> void BinaryTree<T>::PostOutput() { outputString=""; PostOrder(Output,root); outputString.erase(outputString.end()-1); cout<<outputString<<endl; } template<class T> void BinaryTree<T>::LevelOutput() { outputString=""; LevelOrder(Output,root); outputString.erase(outputString.end()-1); cout<<outputString<<endl; } template<class T> void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t) { /*************使用递归实现的遍历*************** if(t) { Visit(t); PreOrder(Visit,t->LeftChild); PreOrder(Visit,t->RightChild); } /**********************************************/ /************使用非递归实现的遍历**************/ stack<BinaryTreeNode<T>*>myStack; BinaryTreeNode<T>*pointer = root; while(!myStack.empty()||pointer)//栈不空或者pointer不空 { if(pointer) { Visit(pointer); //访问当前节点 myStack.push(pointer); //当前节点地址入栈 pointer=pointer->LeftChild; //访问左边分支 } else //左子树访问完毕 { pointer=myStack.top(); myStack.pop(); pointer=pointer->RightChild; } } } template<class T> void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t) { /*************使用递归实现的遍历*************** if(t) { InOrder(Visit,t->LeftChild); Visit(t); InOrder(Visit,t->RightChild); } /**********************************************/ /************使用非递归实现的遍历**************/ stack<BinaryTreeNode<T>*>myStack; BinaryTreeNode<T>*pointer = root; while(!myStack.empty()||pointer)//栈不空或者pointer不空 { if(pointer) { myStack.push(pointer); //当前节点地址入栈 pointer=pointer->LeftChild; //访问左边分支 } else //左子树访问完毕 { pointer=myStack.top(); Visit(pointer); //访问当前节点 myStack.pop(); pointer=pointer->RightChild; } } } template<class T> void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t) { /*************使用递归实现的遍历***************/ if(t) { PostOrder(Visit,t->LeftChild); PostOrder(Visit,t->RightChild); Visit(t); } /**********************************************/ /************使用非递归实现的遍历************** StackElement<T>element; stack<StackElement<T>>myStack; BinaryTreeNode<T>*pointer; if(root==NULL) return; pointer=root; while(true) { while(pointer!=NULL) { element.pointer = pointer; element.tag=Left; myStack.push(element); pointer=pointer->LeftChild; } element=myStack.top(); myStack.pop(); pointer=element.pointer; //从右子树回来 while(element.tag==Right) { Visit(pointer->data); if (myStack.empty()) { return } else { element=myStack.top(); myStack.pop(); pointer=element.pointer; } //从左子树回来 element.tag = Right; myStack.push(element); //转向访问右子树 pointer=pointer->RightChild; } } /**********************************************/ } template<class T> void BinaryTree<T>::LevelOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t) { queue<BinaryTreeNode<T>*>myQueue; while(t) { Visit(t); if(t->LeftChild) myQueue.push(t->LeftChild); if(t->RightChild) myQueue.push(t->RightChild); if(!myQueue.empty()) { t=myQueue.front(); myQueue.pop(); }else{ break; } } } template<class T> void BinaryTree<T>::AddNode(const T&u){ if(!root) { root = new BinaryTreeNode<T>; root->data = u; root->LeftChild=0; root->RightChild=0; return ; } BinaryTreeNode<T> *newNode = new BinaryTreeNode<T>; newNode->data = u; queue<BinaryTreeNode<T>*>myQueue; BinaryTreeNode<T>*t; t=root; while(t) { if(t->LeftChild){ myQueue.push(t->LeftChild); } if(t->RightChild){ myQueue.push(t->RightChild); } if(!t->LeftChild) { t->LeftChild=newNode; return; }else{ } if(!t->RightChild) { t->RightChild=newNode; return; }else{ } if(!myQueue.empty()) { t=myQueue.front(); myQueue.pop(); //队列中删除一个节点并且将其赋值给t } } } template<class T> static void Free(BinaryTreeNode<T>*t) { delete t; } template<class T> void BinaryTree<T>::Delete() { PostOrder(Free,root); root = 0; } template<class T> int BinaryTree<T>::Height(BinaryTreeNode<T>*t)const { if(!t) return 0; int hl = Height(t->LeftChild); int hr = Height(t->RightChild); return hl>hr?++hl:++hr; } template<class T> int BinaryTree<T>::Size() { count = 0 ; PreOrder(countTree,root); return count; } int count = 0; BinaryTree<char> a,x,y,z; template<class T> void countTree(BinaryTreeNode<T>*t) { count++; } BinaryTreeNode<char>* creat(char *pre,char *in,int len) { int k; if(len<=0) return NULL; BinaryTreeNode<char> *head=new BinaryTreeNode<char>; head->data=*pre; char *p; for(p=in;*p!=NULL;p++) //应该是*p!= NULL, 而不是p!=NULL if(*p==*pre) break; //判断失败 if (*p == NULL) { printf("NO ANSWER.\n"); return NULL; } k=p-in; head->LeftChild=creat(pre+1,in,k); head->RightChild=creat(pre+k+1,p+1,len-k-1); return head; } void main() { cout<<"Input1"<<endl; string myInput=" "; cin>>myInput; int which = 0; while(myInput[which]) { char temp = myInput[which]; y.AddNode(temp); which++; } cout<<"Output1"<<endl; y.PreOutput(); y.InOutput(); y.PostOutput(); cout<<"Input2"<<endl; string input1; cin>>input1; string input2; cin>>input2; char*preOrder=(char*)input1.c_str(); char*inOrder=(char*)input2.c_str(); BinaryTreeNode<char>*myRoot = creat(preOrder,inOrder,input2.length()); BinaryTree<char>newTree; newTree.MakeTree(myRoot); cout<<"Output2"<<endl; newTree.PostOutput(); newTree.LevelOutput(); cout<<"End"<<endl; }