这次主要是用到二叉树的非递归遍历和层次遍历。孩子兄弟节点表示法保存树的结构。
//============================================================================ // Name : 5.1.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ /** * [实验目的] 验证树和森林的遍历算法。 [实验内容及要求] 定义左儿子—右兄弟链接存储的树类和森林类。 实验验证如下算法的正确性、各种功能及指标: 1)创建树和森林; 2)树和森林的先根遍历的递归和迭代算法; 3)树和森林的后根遍历的递归和迭代算法; 4)树和森林的层次遍历算法。 */ #include <iostream> #include<stack> #include<queue> using namespace std; //借用二叉树的 存储方式来表示孩子兄弟节点的表示方法 typedef struct BinTreeNode{ char data; struct BinTreeNode * left,*right; }BinTreeNode; class BinTree{ private: BinTreeNode *root; public: BinTree(){ cout<<"输入要创建的树,空节点用#代替\n"; root = creat(); } BinTree(BinTreeNode & temp){ root = &temp; temp.left = NULL; temp.right = NULL; } BinTreeNode * getRoot(){ return root; } BinTreeNode * creat(){ //递归创建树 char t; cin>>t; if(t=='#'){// # stand for null return NULL; } else{ BinTreeNode *r = new BinTreeNode; r->data = t; r->left = creat(); r->right = creat(); return r; } } void unPreOrder(void){ //先跟遍历的非递归方法 BinTreeNode *t = root; stack <BinTreeNode*> s; cout<<"\n 非递归方法,先跟遍历:"<<endl; while(t!=NULL||!s.empty()){ while(t!=NULL){ cout<<t->data<<" "; s.push(t); t = t-> left; } if(!s.empty()){ t = s.top(); s.pop(); t = t->right; } } } void unInOrder(){ BinTreeNode *t = root; stack <BinTreeNode*> s; cout<<"\n 非递归方法,中跟遍历:"<<endl; while(t!=NULL||!s.empty()){ while(t!=NULL){ s.push(t); t=t->left; } if(!s.empty()){ t = s.top(); cout<<t->data <<" "; s.pop(); t= t->right; } } } void unPostOrder(){ /** * 要保证根结点在左孩子和右孩子访问之后才能访问, * 因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子, * 则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了, * 则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈, * 这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问, * 左孩子和右孩子都在根结点前面被访问。 * */ cout<<"\n 非递归方法,后跟遍历:"<<endl; stack <BinTreeNode*> s; BinTreeNode *pre = NULL,*cur; s.push(root); while(!s.empty()){ cur = s.top(); if((cur->left==NULL&&cur->right==NULL)|| (pre!=NULL&&(pre==cur->left||pre==cur->right))){ cout<<cur->data<<" ";//如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop(); pre = cur; }else{ if(cur->right!=NULL) s.push(cur->right); if(cur->left!=NULL) s.push(cur->left); } } } void LevelOrder(){ //层次遍历 BinTreeNode *p ; queue <BinTreeNode*> q; cout<<"\n对应二叉树层次遍历"<<endl; if(root!=NULL) q.push(root); while(!q.empty()){ p = q.front(); q.pop(); cout<<p->data<<" "; if(p->left!=NULL) q.push(p->left); if(p->right!=NULL) q.push(p->right); } } void TreeLevelOrder(){ //树层次遍历 BinTreeNode *p ; queue <BinTreeNode*> q; cout<<"\n树的层次遍历"<<endl; if(root!=NULL) q.push(root); while(!q.empty()){ p = q.front(); q.pop(); while(p!=NULL){ cout<<p->data<<" "; if(p->left!=NULL) q.push(p->left); p = p->right; } } } }; void preOrderTra(BinTreeNode *t){ //先跟遍历 -递归 if(t){ cout<<t->data<<" "; preOrderTra(t->left); preOrderTra(t->right); } } void midOrderTra(BinTreeNode *t){ //中跟遍历-递归 if(t){ midOrderTra(t->left); cout<<t->data<<" "; midOrderTra(t->right); } } void bacOrderTra(BinTreeNode *t){ //后跟遍历-递归 if(t){ bacOrderTra(t->left); bacOrderTra(t->right); cout<<t->data<<" "; } } int main() { // 测试数据 (教材87页图) *+A##B##+*-C##D##E##F## // *ab##ck###deh##fj##g### BinTree mb; BinTreeNode *r = mb.getRoot(); //递归遍历 cout<<"先跟遍历-递归"<<endl; preOrderTra(r); cout<<"\n中跟遍历-递归"<<endl; midOrderTra(r); cout<<"\n后跟遍历-递归"<<endl; bacOrderTra(r); //下面几个是非递归遍历 mb.unPreOrder(); mb.unInOrder(); mb.unPostOrder(); mb.LevelOrder();// 二叉树层次遍历 mb.TreeLevelOrder(); //对应树的层次遍历,不过顺序有问题,是层次 return 0; }
运行结果:
转载文章请注明出处: http://www.cnblogs.com/menglei/