递归和非递归实现二叉树的遍历
#include <stdlib.h> #include<stack> #include<string.h> #include<iostream> using namespace std; typedef struct Node{//ABDG##H###CE#I##F## Node* left; Node* right; char data; }Node,*PNode; void create(PNode &T){ char c; scanf("%c",&c); if(c=='#') T=NULL; else{ T=(PNode)malloc(sizeof(Node));//不要忘了申请地址 T->data=c; create(T->left); create(T->right); } } void pre1(PNode &T){ if(T) cout<<T->data<<" "; if(T->left!=NULL) pre1(T->left); if(T->right!=NULL) pre1(T->right); } void pre2(PNode &T){ if(T==NULL) return; stack<PNode>s; PNode p=T; while(!s.empty()||p){ while(p){ cout<<p->data<<" "; s.push(p); p=p->left; } if(!s.empty()){ p=s.top(); s.pop(); p=p->right; } } } void In1(PNode &T){ if(T==NULL) return; if(T->left!=NULL) In1(T->left); cout<<T->data<<" "; if(T->right!=NULL) In1(T->right); } void In2(PNode &T){ if(T==NULL) return; PNode p=T; stack<PNode>s; while(p||!s.empty()){ while(p){ s.push(p); p=p->left; } if(!s.empty()){ p=s.top(); s.pop(); cout<<p->data<<" "; p=p->right; } } } void Post1(PNode &T){ if(T==NULL) return; if(T->left!=NULL) Post1(T->left); if(T->right!=NULL) Post1(T->right); cout<<T->data<<" "; } void Post2(PNode &T){ stack<PNode>s; PNode p=T,r=NULL; while(p||!s.empty()){ if(p){ s.push(p); p=p->left; }else{ p=s.top(); if(p->right&&p->right!=r){ p=p->right; s.push(p); p=p->left; }else{ s.pop(); cout<<p->data<<" "; r=p; p=NULL; } } } } void Post22(PNode &T){ if (T == NULL) return; stack<PNode> s; //pCur:当前访问节点,pLastVisit:上次访问节点 PNode pCur, pLastVisit; pCur = T; pLastVisit = NULL; //先把pCur移动到左子树最下边 while (pCur) { s.push(pCur); pCur = pCur->left; } while (!s.empty()) { //走到这里,pCur都是空,并已经遍历到左子树底端(看成扩充二叉树,则空,亦是某棵树的左孩子) pCur = s.top(); s.pop(); //一个根节点被访问的前提是:无右子树或右子树已被访问过 if (pCur->right == NULL || pCur->right == pLastVisit) { cout <<pCur->data<<" "; //修改最近被访问的节点 pLastVisit = pCur; } /*这里的else语句可换成带条件的else if: else if (pCur->lchild == pLastVisit)//若左子树刚被访问过,则需先进入右子树(根节点需再次入栈) 因为:上面的条件没通过就一定是下面的条件满足。仔细想想! */ else { //根节点再次入栈 s.push(pCur); //进入右子树,且可肯定右子树一定不为空 pCur = pCur->right; while (pCur) { s.push(pCur); pCur = pCur->left; } } } cout << endl; } int main(){ PNode T; // T=(PNode) malloc(sizeof(Node)); create(T); printf("递归前序遍历\n"); pre1(T); cout<<"\n非递归前序遍历"<<endl; pre2(T); cout<<"\n递归中序遍历\n"; In1(T); cout<<"\n非递归中序遍历\n"; In2(T); cout<<"\n递归后序遍历\n"; Post1(T); cout<<"\n非递归后序遍历\n"; Post2(T); return 0; } ////https://blog.csdn.net/z_ryan/article/details/80854233 //#include<iostream> //#include <stdlib.h> //#include<stack> //#include<string.h> //using namespace std; //typedef struct TreeNode{ // TreeNode *left,*right; // char c; //}TreeNode,*pNode; //void create(pNode &T){ // char h; // scanf("%c",&h); // if(h=='#') // T=NULL; // else{ // T=(pNode)malloc (sizeof(TreeNode)); // T->c=h; // create(T->left); // create(T->right); // } //} //void pre1(pNode &T){ // // printf("%c ",T->c); // if(T->left!=NULL) pre1(T->left); // if(T->right!=NULL) pre1(T->right); //} //void pre2(pNode &T){ // stack<pNode>s; // printf("\n非递归前序"); // if(T!=NULL) // s.push(T); // while(!s.empty()){ // pNode p=s.top(); // s.pop(); // printf("%c ",p->c); // if(p->right!=NULL) s.push(p->right); // if(p->left!=NULL) s.push(p->left); // } // //} //void In1(pNode &T){ // // if(T->left!=NULL) In1(T->left); // printf("%c ",T->c); // if(T->right!=NULL) In1(T->right); //} //void In2(pNode &T){ // stack<pNode>s; // printf("\n非递归中序"); // pNode p=T; // while(p!=NULL||!s.empty()){ // if(p!=NULL){ // s.push(p); // p=p->left; // }else{ // p=s.top(); // s.pop(); // printf("%c ",p->c); // p=p->right; // } // } //} //void Tail1(pNode &T){ // if(T->left!=NULL) Tail1(T->left); // if(T->right!=NULL) Tail1(T->right); // printf("%c ",T->c); //} //int main(){ // TreeNode *T;//ABDG##H###CE#I##F## // T=(pNode)malloc(sizeof(TreeNode)); // create(T); // printf("递归前序"); // pre1(T); // pre2(T); // printf("\n递归中序"); // In1(T); // In2(T); // printf("\n递归后序"); // Tail1(T); // return 0; //}