作业 树和森林 遍历(递归/非递归先序,递归/非递归后序,递归层次)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了作业 树和森林 遍历(递归/非递归先序,递归/非递归后序,递归层次)相关的知识,希望对你有一定的参考价值。
1 #include <iostream> 2 #include"queue.h"//之前写的类 3 #include"stack.h" //之前写的类 4 using namespace std; 5 6 template <class T> 7 class Tree; 8 9 //======================================== 10 // 树节点类声明 11 template <class T> 12 class TreeNode 13 { 14 private: 15 TreeNode<T> *firstChild,*nextBrother; 16 //指向大孩子结点的指针和指向大兄弟结点的指针 17 T data;//数据 18 public: 19 friend class Tree<T>; 20 //构造函数 21 TreeNode(const T& item,TreeNode *lptr=NULL,TreeNode *rptr=NULL): 22 data(item),firstChild(lptr),nextBrother(rptr){} 23 24 TreeNode<T> * GetFirstChild()const{return firstChild;}//返回大儿子节点 25 26 void SetFirstChild(TreeNode<T> * L){firstChild=L;}//设置大儿子结点 27 28 TreeNode<T> * GetNextBrother()const{return nextBrother;}//返回大兄弟节点 29 30 void SetNextBrother(TreeNode<T> * R){nextBrother=R;}//设置大兄弟节点 31 32 T GetData(){return data;} 33 34 void SetData(T item){data=item;} 35 36 37 }; 38 39 40 41 //=============================================================== 42 // 树类的声明 43 44 template <class T> 45 class Tree 46 { 47 private: 48 TreeNode<T> *root;//根结点的声明 49 public: 50 Tree(TreeNode<T>*t=NULL):root(t){}//构造函数 51 52 virtual ~Tree(){Del(root);}//析构函数 删除整棵 树 53 54 //在以节点t为根节点的子树中查找data域为item的结点 55 TreeNode<T> *Find(TreeNode<T> *t,const T&item)const; 56 57 //在以节点t为根节点的子树中搜索节点p的父节点 58 TreeNode<T> * Father(TreeNode<T> *t,TreeNode<T> *p)const; 59 60 //在以节点t为根节点的子树中删除节点t及其子树 61 void DelSubTree(TreeNode<T>* t,TreeNode<T> *p); 62 63 //删除节点t及其子树 64 void Del(TreeNode<T> *t); 65 66 //先根遍历并输出以节点t为根节点的子树 67 void PreOrder( TreeNode<T> *t)const; 68 69 //后根遍历并输出以节点t为根节点的子树 70 void PostOrder(TreeNode<T> *t)const; 71 72 73 //非递归先根遍历并输出以节点t为根节点的子树 74 void NorePreOrder(TreeNode<T> *t)const; 75 76 //非递归后根遍历并输出以节点t为根节点的子树 77 void NorePostOrder(TreeNode<T> *t)const; 78 79 //非递归层次遍历并输出以节点t为根节点的子树 80 void NoreLevelOrder(TreeNode<T> *t)const; 81 82 83 //创建树 84 TreeNode<T>* CreateTree(); 85 86 87 //其它操作 88 TreeNode<T>* GetRoot(){return root;} 89 void SetRoot(TreeNode<T> * t){root=t;} 90 bool IsEmpty(){return root==NULL;} 91 92 void output(); 93 94 }; 95 96 template <class T> 97 void Tree<T>::output() 98 { 99 cout<<" 树的先根遍历的序列为:"; 100 PreOrder(GetRoot()); 101 cout<<endl; 102 103 104 cout<<" 树的后根遍历的序列为:"; 105 PostOrder(GetRoot()); 106 cout<<endl; 107 108 cout<<" 树的层次遍历的序列为:"; 109 NoreLevelOrder(GetRoot()); 110 cout<<endl; 111 } 112 113 114 //======================================= 115 //在以节点t为根节点的子树中查找data域为item的结点 116 template <class T> 117 TreeNode<T>* Tree<T>::Find(TreeNode<T> *t,const T&item)const 118 { 119 TreeNode<T> * p; 120 //递归出口 121 if(t==NULL)return NULL; 122 if(t->GetData()==item) return t; 123 //递归 124 p=Find(t->GetFirstChild(),item); 125 if(p!=NULL) return p; 126 127 p=Find(t->GetNextBrother(),item); 128 if(p!=NULL) return p; 129 130 return NULL; 131 } 132 133 134 //在以节点t为根节点的子树中搜索节点p的父结点 135 template <class T> 136 TreeNode<T>* Tree<T>::Father(TreeNode<T>* t,TreeNode<T>*p)const 137 { 138 139 140 if(t==NULL||p==NULL)//若t,p中有一个为空 141 return NULL; 142 if(p==root) return NULL; //若t是根结点则没有父节点 143 144 TreeNode<T>*result=NULL; 145 TreeNode<T>*q=t->GetFirstChild();//从第一棵子树开始搜索 146 while(q!=NULL&&q!=p) 147 { 148 result=Father(q,p); 149 if(!result) q=q->GetNextBrother(); 150 else return result; 151 } 152 if(q==p) return t; 153 return NULL; 154 } 155 156 //====================================== 157 //创建树 158 template <class T> 159 TreeNode<T>* Tree<T>::CreateTree() { 160 cout<<"输入节点"<<endl; 161 TreeNode<T>* t; 162 T data; 163 cin>>data; 164 t=new TreeNode<T>(data); 165 cout<<"该结点的子树数"; 166 int n; 167 cin>>n; 168 if(n!=0) 169 { 170 int i=1; 171 cout<<"创建"<<data<<"的第1棵子树"<<endl; 172 TreeNode<T>*child1=CreateTree(); 173 t->SetFirstChild(child1); 174 i++; 175 while(i<=n) 176 { 177 cout<<"创建"<<data<<"的第"<<i<<"棵子树"<<endl; 178 TreeNode<T>*child2=CreateTree(); 179 child1->SetNextBrother(child2); 180 child1=child2; 181 i++; 182 } 183 } 184 return t; 185 } 186 187 188 //============================================================= 189 //先序遍历树 190 template <class T> 191 void Tree<T>::PreOrder( TreeNode<T>* t) const { 192 if(t == NULL) { 193 return; 194 } 195 cout<<t->GetData()<<" "; 196 PreOrder(t->GetFirstChild()); 197 PreOrder(t->GetNextBrother()); 198 199 } 200 201 template <class T> 202 void Tree<T>::NorePreOrder(TreeNode<T>* t) const{ 203 LStack<TreeNode<T>*> q; 204 if(t!=NULL) { 205 q.Push(t); 206 } 207 TreeNode<T> *node; 208 while(!q.IsEmpty()) { 209 q.Pop(node); 210 cout<<node->GetData()<<" "; 211 if(node->GetFirstChild() != NULL) { 212 q.Push(node->GetFirstChild()); 213 } 214 if(node->GetNextBrother() != NULL) { 215 q.Push(node->GetNextBrother()); 216 } 217 } 218 } 219 //========================================= 220 221 //后序遍历树 222 template <class T> 223 void Tree<T>::PostOrder( TreeNode<T>* t) const { 224 if(t == NULL) { 225 return; 226 } 227 PostOrder(t->GetFirstChild()); 228 cout<<t->GetData()<<" "; 229 PostOrder(t->GetNextBrother()); 230 } 231 232 template <class T> 233 void Tree<T>::NorePostOrder(TreeNode<T>* t) const{ 234 LStack<TreeNode<T>*> s; 235 if(t!=NULL) s.Push(t); 236 TreeNode<T> *node; 237 while(!s.IsEmpty()) { 238 s.Pop(node); 239 if(node->GetFirstChild() != NULL) { 240 s.Push(node->GetFirstChild()); 241 } 242 cout<<node->GetData()<<" "; 243 if(node->GetNextBrother() != NULL) { 244 s.Push(node->GetNextBrother()); 245 } 246 } 247 } 248 249 250 //====================================== 251 //层次遍历,非递归 252 template <class T> 253 void Tree<T>::NoreLevelOrder(TreeNode<T>* t) const{ 254 LStack<TreeNode<T>*> s; 255 LQueue<TreeNode<T>*> q; 256 //所有firstchild都入队,brother入栈 257 if(t!=NULL) { 258 q.QInsert(t); 259 } 260 TreeNode<T> *node; 261 while(!s.IsEmpty()||!q.IsEmpty()) 262 { 263 while(!s.IsEmpty()) 264 { 265 266 s.Pop(node); 267 268 cout<<node->GetData()<<" "; 269 270 if(node->GetFirstChild() != NULL) { 271 q.QInsert(node->GetFirstChild()); 272 } 273 if(node->GetNextBrother() != NULL) { 274 s.Push(node->GetNextBrother()); 275 } 276 } 277 if(!q.IsEmpty()) 278 { 279 q.QDelete(node); 280 281 cout<<node->GetData()<<" "; 282 283 if(node->GetFirstChild() != NULL) { 284 q.QInsert(node->GetFirstChild()); 285 } 286 if(node->GetNextBrother() != NULL) { 287 s.Push(node->GetNextBrother()); 288 } 289 } 290 } 291 } 292 293 //======================================== 294 //删除结点及其左右子树 295 template <class T> 296 void Tree<T>::Del(TreeNode<T> *t) 297 { 298 if(t != NULL) { 299 Del(t->GetFirstChild()); 300 Del(t->GetNextBrother()); 301 delete t; 302 } 303 } 304 305 template <class T> 306 void Tree<T>::DelSubTree(TreeNode<T>* t,TreeNode<T> *p) 307 { 308 309 if(t != NULL&&p!=NULL) { 310 TreeNode<T>*q=NULL,*result=NULL; 311 result=FindFather(t,p); 312 if(result)//如果p父节点存在 313 { 314 if(result->GetFirstChild()==p)//如果p是f的大孩子节点 315 { 316 result->SetFirstChild(p->GetNextBrother()); 317 Del(p); 318 return; 319 } 320 else//如果不是大孩子结点 321 { 322 q=result->GetFirstChild(); 323 while(q->GetNextBrother()!=p) 324 q=q->GetNextBrother(); 325 q->SetNextBrother(p->GetNextBrother()); 326 Del(p); 327 return; 328 } 329 } 330 else 331 { 332 Del(p); 333 root=NULL; 334 } 335 } 336 337 }
森林
#include <iostream> #include"queue.h"//之前写的类 #include"stack.h" //之前写的类 using namespace std; /* 用二叉树的方式实现 root指针指向第一棵树的根节点 */ template <class T> class Forest; //======================================== // 森林节点类声明 template <class T> class ForestNode { private: ForestNode<T> *firstChild,*nextBrother; //指向大孩子结点的指针和指向大兄弟结点的指针 T data;//数据 public: friend class Forest<T>; //构造函数 ForestNode(const T& item,ForestNode *lptr=NULL,ForestNode *rptr=NULL): data(item),firstChild(lptr),nextBrother(rptr){} ForestNode(){} ForestNode<T> * GetFirstChild()const{return firstChild;}//返回大儿子节点 void SetFirstChild(ForestNode<T> * L){firstChild=L;}//设置大儿子结点 ForestNode<T> * GetNextBrother()const{return nextBrother;}//返回大兄弟节点 void SetNextBrother(ForestNode<T> * R){nextBrother=R;}//设置大兄弟节点 T GetData(){return data;} void SetData(T item){data=item;} }; //=============================================================== // 森林类的声明 template <class T> class Forest { private: ForestNode<T> *root;//虚根结点的声明 int number;//树数 public: Forest(ForestNode<T>*t=NULL):root(t){}//构造函数 virtual ~Forest(){Del(root);}//析构函数 删除整个森林 //在以节点t为根节点的森林中查找data域为item的结点 ForestNode<T> *Find(ForestNode<T> *t,const T&item)const; ForestNode<T>* CreateNewTree(); //森林中增加一棵树 ForestNode<T>* CreateTree(); //创建树 ForestNode<T>* GetTree(int n);//获得森林中的第n棵数 //删除节点t及其子森林 void Del(ForestNode<T> *t); //先根遍历并输出以节点t为根节点的子森林 void PreOrder( ForestNode<T> *t)const; //后根遍历并输出以节点t为根节点的子森林 void PostOrder(ForestNode<T> *t)const; //非递归先根遍历并输出以节点t为根节点的子森林 void NorePreOrder(ForestNode<T> *t)const; //非递归后根遍历并输出以节点t为根节点的子森林 void NorePostOrder(ForestNode<T> *t)const; //递归层次遍历并输出以节点t为根节点的子森林 void LevelOrder(ForestNode<T> *t)const; //创建森林 ForestNode<T>* CreateForest(); //其它操作 ForestNode<T>* GetRoot(){return root;} void SetRoot(ForestNode<T> * t){root=t;} bool IsEmpty(){return root==NULL;} void output(); }; template <class T> void Forest<T>::output() { cout<<" 森林的先根遍历的序列为:"; PreOrder(GetRoot()); cout<<endl; cout<<" 森林的后根遍历的序列为:"; PostOrder(GetRoot()); cout<<endl; cout<<" 森林的层次遍历的序列为:"; LevelOrder(GetRoot()); cout<<endl; } //======================================= //在以节点t为根节点的子森林中查找data域为item的结点 template <class T> ForestNode<T>* Forest<T>::Find(ForestNode<T> *t,const T&item)const { ForestNode<T> * p; //递归出口 if(t==NULL)return NULL; if(t->GetData()==item) return t; //递归 p=Find(t->GetFirstChild(),item); if(p!=NULL) return p; p=Find(t->GetNextBrother(),item); if(p!=NULL) return p; return NULL; } //====================================== //创建森林 template <class T> ForestNode<T>* Forest<T>::CreateForest() { ForestNode<T>*p,*t; cout<<"森林中树的数量:"; cin>>number; int i=1; if(number!=0) { cout<<"创建第"<<i<<"棵树"<<endl; t=root=CreateTree(); i++; while(i<=number) { cout<<"创建第"<<i<<"棵树"<<endl; p=CreateTree(); t->SetNextBrother(p); t=p; i++; } } return root; } template <class T> ForestNode<T>* Forest<T>::CreateTree() { cout<<"输入节点的值"; ForestNode<T>* currptr; T data; cin>>data; currptr=new ForestNode<T>(data,NULL,NULL); cout<<"输入该结点的子树数"; int n; cin>>n; int i=1; if(n!=0) { cout<<"创建"<<data<<"的第1棵子树"<<endl; ForestNode<T>* temp1 = CreateTree(); currptr->SetFirstChild(temp1); i++; while(i<=n) { cout<<"创建"<<data<<"的第"<<i<<"棵子树"<<endl; ForestNode<T>* temp2=CreateTree(); temp1->SetNextBrother(temp2); temp1=temp2; temp2=NULL; i++; } } return currptr; } template <class T> ForestNode<T>* Forest<T>::CreateNewTree()//在森林中增加一棵树 { ForestNode<T>* p=CreateTree(); ForestNode<T>* t=root; while(t->GetNextBrother()!=NULL) t=t->GetNextBrother(); t->SetNextBrother(p); return p; } template <class T> ForestNode<T>* Forest<T>::GetTree(int k)//返回第k棵树 { if(k>number&&k<1) return NULL;//越界 int i=1; ForestNode<T>*t=root; while(i!=k) { t=t->GetNextBrother(); i++; } return t; } //============================================================= //先序遍历森林 template <class T> void Forest<T>::PreOrder( ForestNode<T>* t) const { if(t == NULL) { return; } cout<<t->GetData()<<" "; PreOrder(t->GetFirstChild()); PreOrder(t->GetNextBrother()); } template <class T> void Forest<T>::NorePreOrder(ForestNode<T>* t) const{ LStack<ForestNode<T>*> q; if(t!=NULL) { q.Push(t); } ForestNode<T> *node; while(!q.IsEmpty()) { q.Pop(node); cout<<node->GetData()<<" "; if(node->GetFirstChild() != NULL) { q.Push(node->GetFirstChild()); } if(node->GetNextBrother() != NULL) { q.Push(node->GetNextBrother()); } } } //========================================= //后序遍历森林 template <class T> void Forest<T>::PostOrder( ForestNode<T>* t) const { if(t == NULL) { return; } PostOrder(t->GetFirstChild()); cout<<t->GetData()<<" "; PostOrder(t->GetNextBrother()); } template <class T> void Forest<T>::NorePostOrder(ForestNode<T>* t) const{ LStack<ForestNode<T>*> q; if(t!=NULL) { q.Push(t); } ForestNode<T> *node; while(!q.IsEmpty()) { q.Pop(node); if(node->GetFirstChild() != NULL) { q.Push(node->GetFirstChild()); } cout<<node->GetData()<<" "; if(node->GetNextBrother() != NULL) { q.Push(node->GetNextBrother()); } } } //====================================== //层次遍历 template <class T> void Forest<T>::LevelOrder(ForestNode<T>* t) const{ LStack<ForestNode<T>*> s; LQueue<ForestNode<T>*> q; //所有firstchild都入队,brother入栈 if(t!=NULL) { q.QInsert(t); } ForestNode<T> *node; while(!s.IsEmpty()||!q.IsEmpty()) { while(!s.IsEmpty()) { s.Pop(node); cout<<node->GetData()<<" "; if(node->GetFirstChild() != NULL) { q.QInsert(node->GetFirstChild()); } if(node->GetNextBrother() != NULL) { s.Push(node->GetNextBrother()); } } if(!q.IsEmpty()) { q.QDelete(node); cout<<node->GetData()<<" "; if(node->GetFirstChild() != NULL) { q.QInsert(node->GetFirstChild()); } if(node->GetNextBrother() != NULL) { s.Push(node->GetNextBrother()); } } } } //======================================== //删除森林 template <class T> void Forest<T>::Del(ForestNode<T> *t) { if(t != NULL) { Del(t->GetFirstChild()); Del(t->GetNextBrother()); delete t; } }
以上是关于作业 树和森林 遍历(递归/非递归先序,递归/非递归后序,递归层次)的主要内容,如果未能解决你的问题,请参考以下文章