#include <iostream> #include <cstring> #include <stack> #include <cstring> #include <cstdio> #include <vector> using namespace std; struct BTNode { char data; struct BTNode *lchild; struct BTNode *rchild; }; typedef struct BTNode BTNode; //先序建立 //abc##de#g##f### BTNode* creat(BTNode* root) { char s; scanf("%c",&s); if(s=='#') { root=NULL; } else { root=new BTNode; root->data=s; root->lchild=creat(root->lchild); root->rchild=creat(root->rchild); } return root; } void destory(BTNode *root) { if(root) { destory(root->lchild); destory(root->rchild); delete root; } } void visit(BTNode *p) { if(p) { cout<<p->data<<' '; } } void preOrder(BTNode *p) { if(p) { visit(p); preOrder(p->lchild); preOrder(p->rchild); } } void inOrder(BTNode *p) { if(p) { inOrder(p->lchild); visit(p); inOrder(p->rchild); } } void postOrder(BTNode *p) { if(p) { postOrder(p->lchild); postOrder(p->rchild); visit(p); } } void levelOrder(BTNode *root) { if(root == NULL) return; vector<BTNode *> vec; vec.push_back(root); int cur = 0; int last = 1; while(cur < vec.size()) { last = vec.size(); while(cur < last) { visit(vec[cur]); if(vec[cur]->lchild != NULL) vec.push_back(vec[cur]->lchild); if(vec[cur]->rchild != NULL) vec.push_back(vec[cur]->rchild); ++cur; } cout<<endl; } } //计算叶子个数 int countLeaves(BTNode*root) { if(!root->lchild&&!root->rchild) { return 1; } int cnt1=0,cnt2=0; if(root->lchild) { cnt1=countLeaves(root->lchild); } if(root->rchild) { cnt2=countLeaves(root->rchild); } return cnt1+cnt2; } //计算结点数 int countNodes(BTNode *root) { if(root) { return 1+countNodes(root->lchild)+countNodes(root->rchild); } return 0; } //非递归遍历 void preOrder_norecursive(BTNode *root) { stack<BTNode*> st; BTNode *p=root; while(p!=NULL||!st.empty()) { while(p!=NULL) { visit(p); st.push(p); p=p->lchild; } if(!st.empty()) { p=st.top(); st.pop(); p=p->rchild; } } } void inOrder_norecursive(BTNode *root) { stack<BTNode*> st; BTNode *p=root; while(p!=NULL||!st.empty()) { while(p!=NULL) { st.push(p); p=p->lchild; } if(!st.empty()) { p=st.top(); visit(p); st.pop(); p=p->rchild; } } } /* 要保证根结点在左孩子和右孩子访问之后才能访问, 因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子, 则可以直接访问它;或者P存在左孩子或者右孩子, 但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。 若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候, 左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。 */ void postOrder_norecursive(BTNode *root) { stack<BTNode*> s; BTNode *cur; //当前结点 BTNode *pre=NULL; //前一次访问的结点 s.push(root); while(!s.empty()) { cur=s.top(); if((cur->lchild==NULL&&cur->rchild==NULL)|| (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))) { cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop(); pre=cur; } else { if(cur->rchild!=NULL) s.push(cur->rchild); if(cur->lchild!=NULL) s.push(cur->lchild); } } } int main() { //abc##de#g##f### BTNode* root; root=creat(root); preOrder(root); cout<<endl; inOrder(root); cout<<endl; postOrder(root); cout<<endl; levelOrder(root); cout<<endl; cout<<"countNodes="<<countNodes(root)<<endl; cout<<"countLeaves="<<countLeaves(root)<<endl; preOrder_norecursive(root); cout<<endl; inOrder_norecursive(root); cout<<endl; postOrder_norecursive(root); cout<<endl; destory(root); return 0; }