作业 树和森林 遍历(递归/非递归先序,递归/非递归后序,递归层次)

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;
	}
}	 

  

以上是关于作业 树和森林 遍历(递归/非递归先序,递归/非递归后序,递归层次)的主要内容,如果未能解决你的问题,请参考以下文章

二叉树先序遍历 递归 非递归

二叉树遍历(先序,中序,后序,层序)递归和非递归形式

二叉树先序非递归遍历C语言算法

《数据结构》遍历二叉树的非递归算法的疑问。

二叉树先序中序后序遍历 递归与非递归 Python实现

leetcode144-先序遍历非递归实现