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

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

  

时间: 2024-11-17 22:46:42

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

二叉树的遍历,递归,迭代,层序,中序,前序,后序

#include<stdio.h> #include<stdlib.h> #include<queue> #include<stack> #include<iostream> using namespace std; struct node{ int key; node *left, *right; }; void insertTree(node* &root,int val) { node* tmp = (node*)malloc(si

二叉树的层次遍历(队列) and 二叉搜索树的后序遍历序列

(一)从上往下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印.[层次遍历] 从上到下打印二叉树的规律:每一次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放到一个队列的末尾.接下来到队列的头部取出最早进入队列的节点,重复前面的操作,直至队列中所有的节点都被打印出来为止. //二叉树的层次遍历#include<iostream>#include<queue>using namespace std; typedef int ElemType;typedef st

输入层次遍历,输出中序,前序,后序遍历

题目描述 输入完全二叉树的层次遍历序列,输出该完全二叉树的中序遍历序列. 例如下面二叉树的层次遍历序列为“ABCDE",中序遍历为"DBEAC". A /    \ B      C /    \ D     E 遍历数采用递归写法,无需多说:而且前,中,后,皆为一法: 重要的是看怎么建立一个二叉树,且听分解: //输入层次遍历输出中序 #include <cstdio>#include <cstdlib>#include <cstring>

2015-03-15---二叉树递归(非递归)实现先序、中序、后序遍历(附代码)

今天说好的不碰代码的,后来还是没忍住,学了学数据结构和算法,就先讲讲先序中序和后序遍历吧,我还写了代码,一套递归方式实现遍历二叉树,还有两套非递归方式遍历二叉树, 从简单的开始,因为二叉树的所有操作都是要求在能够遍历的基础上啊. 学过数据结构的肯定都明白遍历顺序, 先序遍历就是先自己,然后左子树,然后右子树, 中序遍历就是先左子树,然后自己,然后右子树 后序遍历就是先左子树,然后右子树,然后自己 比如上图这个很简单的二叉树: 先序遍历:1 2 4 5 3 6 7 中序遍历:4 2 5 1 6 3

【数据结构】 非递归前中后序遍历二叉树

数据结构学的递归了,深入了解后写一个三序非递归的版本. //测试数据:abd##eg##h##c#f## #include <cstdio> #include <iostream> typedef char ElemType; typedef struct Node { ElemType elem; struct Node *lchild,*rchild; }Node,*BiTree; typedef struct{ BiTree *base; BiTree *top; int s

二叉树基本操作续二:前序、中序、后序遍历(非递归 迭代方式)

这里给出二叉树三种遍历方式的迭代实现代码.二叉树的递归实现使用系统栈入栈出栈,而非递归的迭代实现方法就是手动维护一个栈,来模拟递归的入栈出栈过程. 本文没有给出用户栈的代码,如果需要结合上篇的测试代码一起测试,则需要自己实现自己的栈,以及基本的pop.push等栈操作函数. 前序迭代遍历: 1 void iter_preorder(tree_pointer ptr) 2 { 3 //前序遍历:先遍历根节点,然后再分别遍历左右子树 4 int top = -1; 5 tree_pointer st

数据结构 递归和非递归方式实现二叉树先序、中序和后序遍历

二叉树的先序遍历顺序是根.左.右:中序遍历顺序是左.根.右:后序遍历顺序是左.右.根. 递归方式实现如下: 1 public class TreeNode { 2 private int value; 3 private TreeNode left, right; 4 5 public TreeNode(int data) { 6 value = data; 7 } 8 9 // 递归方式实现先序遍历 10 public void preorder(TreeNode treeNode) { 11

二叉树的前中后序遍历简单的递归

二叉树的遍历 无外乎广度和深度 其中深度又分为前中后序遍历三种情况  这三种遍历若只是递归方法 自然很是简单 但递归代码简单 若嵌套层次太深 会栈溢出 二叉树节点数据结构: struct Binary_node{    int val;    Binary_node *left;    Binary_node *right;    Binary_node(int v = 0, Binary_node *le = nullptr, Binary_node *ri = nullptr) :val(v

二叉树的前序遍历、后序遍历、中序遍历规则(递归)

1.前序遍历的规则:(根左右) (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 对于图中二叉树,前序遍历结果:ABDECF 2.中序遍历的规则:(左根右) (1)中序遍历左子树 (2)访问根节点 (3)中序遍历右子树 对于图中二叉树,中序遍历结果:DBEAFC 3.后序遍历二叉树的规则:(左右根) (1)后序遍历左子树 (2)后序遍历右子树 (3)访问根节点 对于图中二叉树,后序遍历结果:DEBFCA 例题:POJ2255 给了前.中序遍历,求后序遍历.参考:https://blo