树和森林v2.0 层次非递归创建树和森林,森林中的树不连

#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
{
	LQueue<ForestNode<T>*> q;
	ForestNode<T>*s=NULL;
	//所有firstchild都入队,brother立即访问
    if(t!=NULL) {
       	q.QInsert(t);
   	}
    ForestNode<T> *node;
    while(s!=NULL||!q.IsEmpty())
	{
	  	while(s!=NULL)
		{
			node=s;
			s=NULL;
			cout<<node->GetData()<<" ";

      		if(node->GetFirstChild() != NULL) {
         		q.QInsert(node->GetFirstChild());
      		}
      		if(node->GetNextBrother() != NULL) {
      			s=node->GetNextBrother();
			}
   		}
   		if(!q.IsEmpty())
   		{
		   	q.QDelete(node);

			cout<<node->GetData()<<" ";

      		if(node->GetFirstChild() != NULL) {
         		q.QInsert(node->GetFirstChild());
      		}
      		if(node->GetNextBrother() != NULL) {
      			s=node->GetNextBrother();
			  }
   		}
	}
}

//========================================
//删除森林
template <class T>
void Forest<T>::Del(ForestNode<T> *t)
{
	if(t != NULL) {
    Del(t->GetFirstChild());
    Del(t->GetNextBrother());
    delete t;
	}
}

 

#include <iostream>
#include"queue.h"
#include"stack.h"
using namespace std;

template <class T>
class Tree;

//========================================
// 树节点类声明
template <class T>
class TreeNode
{
private:
    TreeNode<T>  *firstChild,*nextBrother;
	//指向大孩子结点的指针和指向大兄弟结点的指针
    T data;//数据
public:
	friend class Tree<T>;
    //构造函数
    TreeNode(const T& item,TreeNode *lptr=NULL,TreeNode *rptr=NULL):
        data(item),firstChild(lptr),nextBrother(rptr){}

    TreeNode<T> * GetFirstChild()const{return firstChild;}//返回大儿子节点

    void SetFirstChild(TreeNode<T> * L){firstChild=L;}//设置大儿子结点 

    TreeNode<T> * GetNextBrother()const{return nextBrother;}//返回大兄弟节点

    void SetNextBrother(TreeNode<T> * R){nextBrother=R;}//设置大兄弟节点

    T GetData(){return data;}

    void SetData(T item){data=item;}

};

//===============================================================
// 树类的声明

template <class T>
class Tree
{
private:
    TreeNode<T> *root;//根结点的声明
	T stop;
public:

    Tree(TreeNode<T>*t=NULL):root(t),stop(‘*‘){}//构造函数

    virtual ~Tree(){Del(root);}//析构函数 删除整棵 树

    //在以节点t为根节点的子树中查找data域为item的结点
    TreeNode<T>  *Find(TreeNode<T> *t,const T&item)const;

    //在以节点t为根节点的子树中搜索节点p的父节点
    TreeNode<T> * Father(TreeNode<T> *t,TreeNode<T> *p)const;

	//在以节点t为根节点的子树中删除节点t及其子树
	void DelSubTree(TreeNode<T>* t,TreeNode<T> *p);

    //删除节点t及其子树
    void Del(TreeNode<T> *t);

    //先根遍历并输出以节点t为根节点的子树
    void PreOrder( TreeNode<T> *t)const;

    //后根遍历并输出以节点t为根节点的子树
    void PostOrder(TreeNode<T> *t)const;

    //非递归先根遍历并输出以节点t为根节点的子树
   	void NorePreOrder(TreeNode<T> *t)const;

    //非递归后根遍历并输出以节点t为根节点的子树
  	void NorePostOrder(TreeNode<T> *t)const;

    //非递归层次遍历并输出以节点t为根节点的子树
    void NoreLevelOrder(TreeNode<T> *t)const;

    //创建树
    TreeNode<T>* CreateTree();

    //其它操作
    TreeNode<T>* GetRoot(){return root;}
    void SetRoot(TreeNode<T> * t){root=t;}
    bool IsEmpty(){return root==NULL;}

    void output();

};

template <class T>
void Tree<T>::output()
{
	cout<<" 树的先根遍历的序列为:";
    PreOrder(GetRoot());
    cout<<endl;

    cout<<" 树的后根遍历的序列为:";
    PostOrder(GetRoot());
    cout<<endl;

    cout<<" 树的层次遍历的序列为:";
    NoreLevelOrder(GetRoot());
    cout<<endl;
}

//=======================================
//在以节点t为根节点的子树中查找data域为item的结点
template <class T>
TreeNode<T>* Tree<T>::Find(TreeNode<T> *t,const T&item)const
{
    TreeNode<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;
}

//在以节点t为根节点的子树中搜索节点p的父结点
template <class T>
TreeNode<T>* Tree<T>::Father(TreeNode<T>* t,TreeNode<T>*p)const
{

	if(t==NULL||p==NULL)//若t,p中有一个为空
		return NULL;
	if(p==root) return NULL; //若t是根结点则没有父节点 

	TreeNode<T>*result=NULL;
	TreeNode<T>*q=t->GetFirstChild();//从第一棵子树开始搜索
	while(q!=NULL&&q!=p)
	{
		result=Father(q,p);
		if(!result) q=q->GetNextBrother();
		else return result;
	}
	if(q==p) return t;
	return NULL;
}

//======================================
//非递归创建树
template <class T>
TreeNode<T>* Tree<T>::CreateTree() {

	LQueue<TreeNode<T>*> Q;

	//处理根结点
	//cout<<"输入根结点,并回车\n";
	cout<<"输入根结点\n" ;
	T item;
	//item=getchar();
	cin>>item;
	if(item==stop)
		return NULL;
	root=new TreeNode<T>(item);
	Q.QInsert(root);

	TreeNode<T>* node;
	TreeNode<T>* child;
	while(!Q.IsEmpty())
	{

		Q.QDelete(node);
		//getchar();//过滤回车
		//cout<<"输入"<<node->GetData()<<"的子节点( 用*结尾),并回车\n";
		//item=getchar();
		cout<<"输入"<<node->GetData()<<"的子节点\n";
		cin>>item;
		while(item!=stop)
		{
			if(node->GetFirstChild()==NULL)
			{

				child=new TreeNode<T>(item);
				node->SetFirstChild(child);
				Q.QInsert(child);
				//item=getchar();
			}
			else
			{
				TreeNode<T>*nextchild=new TreeNode<T>(item);
				child->SetNextBrother(nextchild);
				Q.QInsert(nextchild);
				child=nextchild;
				//item=getchar();
			}
			cin>>item;
		}
	}
	output();
	return root;
}

//=============================================================
//先序遍历树
template <class T>
void Tree<T>::PreOrder( TreeNode<T>* t) const {
   if(t == NULL) {
      return;
   }
   cout<<t->GetData()<<" ";
   PreOrder(t->GetFirstChild());
   PreOrder(t->GetNextBrother());

}

template <class T>
void Tree<T>::NorePreOrder(TreeNode<T>* t) const{
    LStack<TreeNode<T>*> q;
    if(t!=NULL) {
       	q.Push(t);
   	}
    TreeNode<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 Tree<T>::PostOrder( TreeNode<T>* t) const {
   	if(t == NULL) {
      	return;
   	}
   	PostOrder(t->GetFirstChild());
   	cout<<t->GetData()<<" ";
   	PostOrder(t->GetNextBrother());
}

template <class T>
void Tree<T>::NorePostOrder(TreeNode<T>* t) const{
    LStack<TreeNode<T>*> s;
    if(t!=NULL) s.Push(t);
    TreeNode<T> *node;
    while(!s.IsEmpty()) {
    	s.Pop(node);
		if(node->GetFirstChild() != NULL) {
         	s.Push(node->GetFirstChild());
      	}
      	cout<<node->GetData()<<" ";
      	if(node->GetNextBrother() != NULL) {
         	s.Push(node->GetNextBrother());
      	}
   	}
}

//======================================
//层次遍历,非递归
template <class T>
void Tree<T>::NoreLevelOrder(TreeNode<T>* t) const{
    LQueue<TreeNode<T>*> q;
	TreeNode<T>*s=NULL;
	//所有firstchild都入队,brother立即访问
    if(t!=NULL) {
       	q.QInsert(t);
   	}
    TreeNode<T> *node;
    while(s!=NULL||!q.IsEmpty())
	{
	  	while(s!=NULL)
		{
			node=s;
			s=NULL;
			cout<<node->data<<" ";

      		if(node->GetFirstChild() != NULL) {
         		q.QInsert(node->GetFirstChild());
      		}
      		if(node->GetNextBrother() != NULL) {
      			s=node->GetNextBrother();
			}
   		}
   		if(!q.IsEmpty())
   		{
		   	q.QDelete(node);

			cout<<node->GetData()<<" ";

      		if(node->GetFirstChild() != NULL) {
         		q.QInsert(node->GetFirstChild());
      		}
      		if(node->GetNextBrother() != NULL) {
      			s=node->GetNextBrother();
			  }
   		}
	}
}

//========================================
//删除结点及其左右子树
template <class T>
void Tree<T>::Del(TreeNode<T> *t)
{
	if(t != NULL) {
    Del(t->GetFirstChild());
    Del(t->GetNextBrother());
    delete t;
	}
}	 

template <class T>
void Tree<T>::DelSubTree(TreeNode<T>* t,TreeNode<T> *p)
{

	if(t != NULL&&p!=NULL) {
		TreeNode<T>*q=NULL,*result=NULL;
		result=FindFather(t,p);
		if(result)//如果p父节点存在
		{
			if(result->GetFirstChild()==p)//如果p是f的大孩子节点
			{
				result->SetFirstChild(p->GetNextBrother());
				Del(p);
				return;
			}
			else//如果不是大孩子结点
			{
				q=result->GetFirstChild();
				while(q->GetNextBrother()!=p)
					q=q->GetNextBrother();
				q->SetNextBrother(p->GetNextBrother());
				Del(p);
				return;
			}
		}
		else
		{
			Del(p);
			root=NULL;
		}
	}

}

 如题,没什么好说的。。

时间: 2024-10-06 04:32:39

树和森林v2.0 层次非递归创建树和森林,森林中的树不连的相关文章

变形二叉树中节点的最大距离(树的最长路径)——非递归解法

问题描述: 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数. 写一个程序,求一棵二叉树中相距最远的两个节点之间的距离.测试用的树: n1 /             \ n2             n3 /        \ n4          n5 /     \         /   \ n6    n7    n8    n9 /                       / n10                

二叉树的非递归遍历(先序、中序、后序和层序遍历)

[前文] 二叉树的非递归遍历有 先序遍历.中序遍历 .后续遍历 和 层序遍历. 非递归算法实现的基本思路:使用堆栈.而层序遍历的实现:使用队列. 如下图所示的二叉树: 前序遍历顺序为:ABCDE (先访问根节点,然后先序遍历其左子树,最后先序遍历其右子树) 中序遍历顺序为:CBDAE (先中序遍历其左子树,然后访问很节点,最后中序遍历其右子树) 后续遍历顺序为:CDBEA (先后序遍历其左子树,然后后续其右子树,最后访问根节点) 层序遍历顺序为:ABECD (由上至下.从左到右遍历二叉树) [准

学习日志---非递归二叉树游标遍历(前中后层序)

实现: //二叉树类 public class MyBiTree { private MyBiTreeNode  root;//根节点 MyBiTree() { this.root = null; } MyBiTree(Object data,MyBiTree left,MyBiTree right) { MyBiTreeNode l,r; if(left==null) { l = null; } else {    l=left.root;  } if(right==null) { r = n

非递归求二叉树的前序、中序和后序遍历

一.前序遍历 分析: 1.前序遍历是中左右,因此利用栈,记录栈顶根结点的同时,先压右子树,后压左子树,从而先遍历左子树. 2.每次弹出的栈顶结点符合前序遍历的顺序,因此可直接记录. 3.注意:由于压入栈的是树的结点,所以栈内数据类型为Node*. struct Node{ int val; Node *left, *right; }; vector<int> get_preorder(Node *root){ vector<int> preorder; stack<Node*

二叉树的非递归遍历(先序, 中序, 后序)

先序遍历: /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> preorderTraversal(TreeNode *root) { stack&

数据结构之关于树的操作(树的递归和非递归遍历)-(四补)

前面写了一些关于树的操作,但是没有实现树的遍历的非递归写法. 通常树有四种遍历方法:1.层次遍历(需要用到树的高度,此文没有考虑) 2.前序遍历(根左右):3.中序遍历(左根右):4.后序遍历(左右根) 树的结构如下: 层次遍历:123456789 前序遍历:124895367 中序遍历:849251637 后序遍历:894526731 java代码实现三种遍历的递归和和非递归实现 package com.lip.datastructure.tree; import java.util.Stac

(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树

写了一点haffman树的创建和二叉树的非递归遍历. 如果编写代码的时候出现了,思维断点,可以借鉴一下, 避免浪费一些不必要的时间. 我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占 位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我 是占位符我是占位符我是占位符我是占位符我是占位符我是 占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符

数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作

AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1). 也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树). 对Avl树进行相关的操作最重要的是要保持Avl树的平衡条件.即对Avl树进行相关的操作后,要进行相应的旋转操作来恢复Avl树的平衡条件. 对Avl树的插入和删除都可以用递归实现,文中也给出了插入的非递归版本,关键在于要用到栈. 代码如下: #inclu

c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 4,层级遍历 二叉树的查找,求高度,求个数,求父节点,复制二叉树,释放二叉树 编译方法,用gcc编译不过去,用g++编译,命令如下: g++ -g nodestack.c nodequeue.c bintree.c