森林和树的C++实现

一、森林和二叉树的转换

1. 同一级树的的节点以二叉树右节点表示;

2. 子节点以二叉树左节点表示;

二、节点的构造


图 2-1 树的节点构造

三、完整源码

Tree.h

#ifndef _TREE_H
#define _TREE_H

#include <iostream>
using namespace std;

template<typename Type>
class Tree;

template<typename Type>
class TreeNode//以二叉树存储森林或者树
{
	friend class Tree<Type>;
public:
	TreeNode() :data(Type()), child(NULL), brother(NULL)
	{}
	TreeNode(Type d) :data(d), child(NULL), brother(NULL)
	{}
private:
	Type data;
	TreeNode<Type> *child;//孩子
	TreeNode<Type> *brother;//兄弟
};

template<typename Type>
class Tree
{
public:
	Tree(Type d) :first(NULL)
	{
		StopFlag = d;
	}
	~Tree()
	{
		Destory();
		StopFlag = 0;
	}
public:
	//以完整深度序列创建树
	void CreateTree(const char *str)
	{
		CreateTree(first,str);
	}
	TreeNode<Type> *Child(TreeNode<Type> *&t)const
	{
		return t->child;
	}
	TreeNode<Type> *NextBrother(TreeNode<Type> *&t)const
	{
		return t->brother;
	}
	TreeNode<Type> *PrioBrother(TreeNode<Type> *&p)const
	{
		return PrioBrother(first, p);
	}
	TreeNode<Type> *Find(Type x)const
	{
		return Find(first, x);
	}
	TreeNode<Type> *Parent(TreeNode<Type> *p)const
	{
		return Parent(first, p);
	}
	void PrintDeep()const
	{
		PrintDeep(first);
	}
	void PrintLength()const
	{
		PrintLength(first);
	}
	void Destory()
	{
		Destory(first);
	}
	bool IsForest()
	{
		return (first->brother != NULL);
	}
private:
	void Destory(TreeNode<Type> *t);
	void PrintLength(TreeNode<Type> *t)const;
	void PrintDeep(TreeNode<Type> *t)const;
	TreeNode<Type> *Parent(TreeNode<Type> *t, TreeNode<Type>*p)const;
	TreeNode<Type> *Find(TreeNode<Type>* t, Type x)const;
	TreeNode<Type> *PrioBrother(TreeNode<Type> *t, TreeNode<Type> *&p)const;
	void CreateTree(TreeNode<Type> *&t, const char *&str);
private:
	TreeNode<Type> *first;
	Type StopFlag; //停止标记
};

template<typename Type>
void Tree<Type>::Destory(TreeNode<Type> *t)
{
	if (t == NULL)
		return;
	//递归摧毁
	Destory(t->child);
	Destory(t->brother);
	delete t;
}

template<typename Type>
void Tree<Type>::PrintLength(TreeNode<Type> *t)const
{
	if (t == NULL)
		return;
	cout << t->data;
	PrintLength(t->brother);//->
	PrintLength(t->child);	//↓
}


template<typename Type>
void Tree<Type>::PrintDeep(TreeNode<Type> *t)const
{
	if (t == NULL)
		return;
	cout << t->data;
	PrintDeep(t->child);	//↓
	PrintDeep(t->brother);	//->
}

template<typename Type>
TreeNode<Type> *Tree<Type>::Parent(TreeNode<Type> *t, TreeNode<Type>*p)const
{
	if (t == NULL || p == NULL)
		return NULL;
	TreeNode<Type> *q = p;
	TreeNode<Type> *qq = q;
	while (q = PrioBrother(q))
	{
		qq = q;
	}
	if (t->child == qq)
		return t;
	TreeNode<Type> *ptr = Parent(t->brother, qq);
	if (ptr == NULL)//未找到
		ptr = Parent(t->child, qq);
	return ptr;
}

template<typename Type>
TreeNode<Type> *Tree<Type>::PrioBrother(TreeNode<Type> *t, TreeNode<Type> *&p)const
{
	if (t == NULL || p == NULL)
		return NULL;
	if (t->brother == p)
		return t;
	TreeNode<Type> *q;
	q = PrioBrother(t->child, p);
	if (q == NULL)//未找到
		q = PrioBrother(t->brother, p);
	return q;
}

template<typename Type>
TreeNode<Type> *Tree<Type>::Find(TreeNode<Type>* t, Type x)const
{
	if (t == NULL)
		return NULL;
	if (t->data == x)
		return t;
	TreeNode<Type> *q;
	q = Find(t->child, x);
	if (q == NULL)//未找到
		q = Find(t->brother, x);
	return q;
}

template<typename Type>
void Tree<Type>::CreateTree(TreeNode<Type> *&t, const char *&str)
{
	char ch = str[0];
	str++;
	if (ch == StopFlag)
	{
		t = NULL;
	}
	else
	{
		t = new TreeNode<Type>(ch);
		CreateTree(t->child, str);
		CreateTree(t->brother, str);
	}
}

#endif

Test.h

#include "Tree.h"

int main(int argc, char *argb[])
{
	//空节点以#表示
	char *str = "ABC##DE##F##G#H##";
	Tree<char> t('#');
	t.CreateTree(str);
	TreeNode<char> *p = t.Find('D');
	TreeNode<char> *q1 = t.NextBrother(p);
	TreeNode<char> *q2 = t.PrioBrother(p);
	TreeNode<char> *q3 = t.Child(p);
	TreeNode<char> *q4 = t.Parent(p);
	t.PrintDeep();//深度优先遍历
	cout << endl;
	t.PrintLength();//广度优先遍历
	cout << endl;
	if (t.IsForest())
		cout << "t is a Forest" << endl;
	else
		cout << "t is a Tree" << endl;
	system("pause");
	return 0;

}
四、测试结果

图 4-1 测试结构


图 4-2  运行结果


  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值