`
宫庆义
  • 浏览: 17305 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

数据结构学习----树类(孩子--兄弟表示)

阅读更多

#include "DCirList.h"
#pragma once
#pragma region
//树类
//测试日期 2010-3-11
#ifndef TREENODE_H
#define TREENODE_H
template<class T>
class TreeNode
{ 
public:
	TreeNode<T>* firstchild;                                     //第一个孩子结点指针
	TreeNode<T>* nextsibling;                                    //下一个兄弟结点指针
	T data;                                                      //数据域
 
	TreeNode(){firstchild=nextsibling=NULL;}                     //构造函数
	TreeNode(T item,TreeNode<T>* pf=NULL,TreeNode<T>* pn=NULL)   //重载构造函数
	{data=item;firstchild=pf;nextsibling=pn;}
};
#endif
#pragma endregion


#pragma region
#ifndef TREE_H
#define TREE_H
template<class T>
class Tree
{
private:
	TreeNode<T>* root;                                            //根结点指针
	TreeNode<T>* current;                                         //当前结点指针
	TreeNode<T>* SearchParent(TreeNode<T>* t,TreeNode<T>* s);     //递归查找父结点
	TreeNode<T>* SearchPrevious(TreeNode<T>* t,TreeNode<T>* s);   //递归查找前驱结点
	TreeNode<T>* Copy(TreeNode<T>* t);                            //拷贝函数
public:
	Tree(){root=current=NULL;}                                    //构造函数 
	~Tree(){ClearTree();}                                         //析构函数 
	void ClearTree(){DeleteSubtree(root);}                        //清空树

	//获取结点指针(8个函数)
	TreeNode<T>* GetRoot()
	{return root;}                                  //返回根结点指针
	TreeNode<T>* GetCurrent()
	{return current;}                               //返回当前结点指针
	TreeNode<T>* GetParent();                       //返回当前结点的父结点的指针
	TreeNode<T>* GetPrevious();                     //返回当前结点的前驱结点的指针
	TreeNode<T>* GetFirstChild()                    //返回当前结点的第一个孩子结点的指针
	{return current==NULL?NULL:current->firstchild;}
	TreeNode<T>* GetLastChild();                    //返回当前结点的最后一个孩子结点的指针
	TreeNode<T>* GetNextSibling()                   //返回当前结点的兄弟结点的指针
	{return current==NULL?NULL:current->nextsibling;}
	TreeNode<T>* GetChild(int i);                   //返回当前结点的第i个孩子结点的指针

 

	//三种遍历(3个函数)
	void PreOrder(TreeNode<T> *t,void(*visit)(T x));   //先根遍历以t为根结点的数据域
	void PosOrder(TreeNode<T> *t,void(*visit)(T x));   //后根遍历以t为根结点的数据域
	void LevelOrder(TreeNode<T> *t,void(*visit)(T x)); //层序遍历以t为根结点的数据域
  
	//设置当前结点,并返回当前结点指针(8个函数)
	TreeNode<T>* SetRoot()
	{return current=root;}                     //把根结点设置为当前结点
	TreeNode<T>* SetCurrent(TreeNode<T> *t)
	{return current=t;}                        //把t所指向的结点设置为当前结点
	TreeNode<T>* SetParent()
	{return current=GetParent();}              //把当前结点的父结点设置为当前结点
	TreeNode<T>* SetPrevious() 
	{return current=GetPrevious();}            //把当前结点的前驱结点设置为当前结点
	TreeNode<T>* SetFirstChild()
	{return current=GetFirstChild();}          //把当前结点的第一个孩子结点设置为当前结点
	TreeNode<T>* SetLastChild()
	{return current=GetLastChild();}           //把当前结点的最后一个孩子结点设置为当前结点
	TreeNode<T>* SetNextSibling()
	{return current=GetNextSibling();}         //把当前结点的兄弟结点设置为当前结点
	TreeNode<T>* SetChild(int i)
	{return current=GetChild(i);}              //把当前结点的第i个孩子结点设置为当前结点


	//插入与删除(6个函数)
	void InsertFirstChild(T x);                //把x插入为当前结点的第一个孩子结点
	void InsertLastChild(T x);                 //把x插入为当前结点的最后一个孩子结点
	void InsertChild(int i,T x);               //把x插入为当前结点的第i个孩子结点
    void InsertSibling(T x);                   //把x插入为当前结点的下一个兄弟结点
	void DeleteSubtree(TreeNode<T>* &t);       //删除以t为根结点的子树
	void DeleteChild(int i);                   //删除当前结点的第i个孩子结点

	//其他操作(2个函数)
	bool IsEmpty(){return root==NULL?true:false;}    //判断是否为空树
	Tree<T>& operator=(Tree<T>& tree);               //运算符重载
};
#endif
#pragma endregion


#pragma region
template<class T>
TreeNode<T>* Tree<T>::SearchParent(TreeNode<T> *t, TreeNode<T> *s)
{
	if(t==NULL||s==NULL||s==root) return NULL;
	TreeNode<T>* p=t->firstchild; 
	for(;p!=NULL;p=p->nextsibling)
	{
		if(p==s) return t;
		SearchParent(p,s);  
	} 
	return NULL;
}
template<class T>
TreeNode<T>* Tree<T>::SearchPrevious(TreeNode<T> *t, TreeNode<T> *s)
{
    if(t==NULL||s==NULL||s==root) return NULL;
	if(t->firstchild==s||t->nextsibling==s) return t;
	TreeNode<T> *p=NULL;
	if((p=SearchPrevious(t->firstchild,s))!=NULL) return p;
	if((p=SearchPrevious(t->nextsibling,s))!=NULL) return p;
}
template<class T>
TreeNode<T>* Tree<T>::Copy(TreeNode<T> *t)
{
	if(t==NULL) return NULL;
	TreeNode<T>* p=new TreeNode<T>();
	p->data=t->data;
	p->firstchild=Copy(t->firstchild);
	p->nextsibling=Copy(t->nextsibling);
	return p;
}
template<class T>
TreeNode<T>* Tree<T>::GetParent()
{
    return SearchParent(root,current);
}
template<class T>
TreeNode<T>* Tree<T>::GetPrevious()
{
	return SearchPrevious(root,current);
}
template<class T>
TreeNode<T>* Tree<T>::GetLastChild()
{
	if(current==NULL) return NULL;
	TreeNode<T>* p=current->firstchild;
	for(;p->nextsibling!=NULL;p=p->nextsibling);
	return p;
}
template<class T>
TreeNode<T>* Tree<T>::GetChild(int i)
{
	if(current==NULL||i<0) return NULL;
	TreeNode<T>* p=current->firstchild; 
	for(int k=0;p!=NULL&&k<i;k++) 
		p=p->nextsibling;  
	return p;
}
template<class T>
void Tree<T>::PreOrder(TreeNode<T> *t, void (*visit)(T))
{
	if(t==NULL) return;
	visit(t->data);
	if(t->firstchild!=NULL)  PreOrder(t->firstchild,visit);
	if(t->nextsibling!=NULL) PreOrder(t->nextsibling,visit);
}
template<class T>
void Tree<T>::PosOrder(TreeNode<T> *t, void (*visit)(T))
{
	if(t==NULL) return;
	if(t->firstchild!=NULL)  PosOrder(t->firstchild,visit);
	visit(t->data);
	if(t->nextsibling!=NULL) PosOrder(t->nextsibling,visit);
}
template<class T>
void Tree<T>::LevelOrder(TreeNode<T> *t, void (*visit)(T))
{
    if(t==NULL) return;
    DCirList<TreeNode<T>*> list;
	TreeNode<T>* p1,*p2;
	list.PushBack(t);
	while(!list.IsEmpty())
	{
		p1=list.PopFront();
		visit(p1->data);
		p2=p1->firstchild;
		while(p2!=NULL)
		{
			list.PushBack(p2);
			p2=p2->nextsibling;
		}
	}
}
template<class T>
void Tree<T>::InsertFirstChild(T x)
{
   TreeNode<T>* newnode=new TreeNode<T>(x);
   if(root==NULL){current=root=newnode; return;} 
   if(current==NULL)return;
   if(current->firstchild!=NULL)
   {
	   TreeNode<T>* p=GetFirstChild();
	   current->firstchild=newnode;
	   newnode->nextsibling=p;
   }
   else
	   current->firstchild=newnode;
}
template<class T>
void Tree<T>::InsertLastChild(T x)
{ 
	TreeNode<T>* newnode=new TreeNode<T>(x);
	if(root==NULL){current=root=newnode; return;} 
	if(current==NULL)return;
	if(current->firstchild!=NULL)
	{
		TreeNode<T>* p=GetLastChild();
		p->nextsibling=newnode;
	}
	else
		current->firstchild=newnode;
}
template<class T>
void Tree<T>::InsertChild(int i, T x)
{  
	TreeNode<T>* newnode=new TreeNode<T>(x);
	if(root==NULL){current=root=newnode; return;} 
	if(current==NULL||i<0)return;
	TreeNode<T>* p=current->firstchild;
	if(p!=NULL)
	{ 
	   if(i==0)
	   {
           newnode->nextsibling=p;
		   current->firstchild=newnode; 
	   }
	   else
	   {
		   p=GetChild(i-1);
		   newnode->nextsibling=p->nextsibling;
		   p->nextsibling=newnode;
	   }
	}
	else
		current->firstchild=newnode;
}
template<class T>
void Tree<T>::InsertSibling(T x)
{
    if(current==NULL||current==root)return;
    TreeNode<T>* newnode=new TreeNode<T>(x);
	newnode->nextsibling=current->nextsibling;
	current->nextsibling=newnode;
}
template<class T>
void Tree<T>::DeleteSubtree(TreeNode<T>* &t)
{
	if(t==NULL) return;
	TreeNode<T> *r,*p1,*p2;
	p1=t->firstchild;  
	while(p1!=NULL)
	{
		p2=p1->nextsibling;
		DeleteSubtree(p1);
		p1=p2;
	}
	r=SearchPrevious(root,t);
	if(r!=NULL)
	{
		if(r->firstchild==t)
			r->firstchild=t->nextsibling;
		if(r->nextsibling==t)
			r->nextsibling=t->nextsibling;
	}
	delete t;
	t=NULL;
}
template<class T>
void Tree<T>::DeleteChild(int i)
{
	TreeNode<T>* p=GetChild(i);
	DeleteSubtree(p);
}
 
template<class T>
Tree<T>& Tree<T>::operator =(Tree<T> &tree)
{
	if(tree.root==NULL) return *this;
	current=root=Copy(tree.root);
	return *this;
}
#pragma endregion
分享到:
评论

相关推荐

    数据结构课件---树

    《数据结构》课程中的树是一种重要的非线性数据结构,...理解并掌握树的这些概念和操作对于学习数据结构和算法至关重要,因为树在计算机科学的许多领域,如文件系统、编译器设计、图形学和数据库中都有着广泛的应用。

    树的孩子兄弟表示法代码.rar

    本资源"树的孩子兄弟表示法代码.rar"提供了一种特殊的树存储方法——孩子兄弟表示法,用C++语言实现,并已通过调试。这种表示法对初学者来说是很有价值的学习材料,特别是对于正在学习数据结构入门阶段的同学。 ...

    南邮数据结构2001-2006

    - 在树 T 中,如果 Y 是 X 的右孩子,则 X 和 Y 是兄弟关系。 - 二叉树 R 的根结点的右子树无法直接确定。 **7. 线性表的插入操作** - 插入操作的平均移动元素次数取决于插入的位置。 - 计算公式为 \(\frac{2n - 1}...

    数据结构--二叉树试验

    用于数据结构二叉树学习,体会递归思想的妙用。

    孩子兄弟树详解(C语言版).rar

    孩子兄弟树,也被称为双链树,是一种特殊的数据结构,它在计算机科学中主要用于表示具有多个子节点的树形结构。这种数据结构扩展了传统的二叉树,每个节点不仅有一个左孩子和一个右孩子,还可以有任意数量的中间孩子...

    数据结构数据结构02-课件_26_26.pdf

    每种方法都有其优缺点,例如双亲表示法查找父节点快速但查找子节点较慢,孩子兄弟表示法则可以将树转换为二叉树,便于利用二叉树的操作。 最后,森林的遍历类似于单棵树的遍历,但涉及到多棵树的情况。森林的先序...

    数据结构 树和二叉树ppt教程

    【数据结构:树和二叉树】 树是一种非线性的数据结构,它的基本概念和术语在计算机科学中至关重要,尤其在算法设计和数据组织中扮演着核心角色。树的定义基于递归,一棵非空树包含一个根节点,以及一组互不相交的...

    c# 树 数据结构

    本压缩包文件“Trees”包含了用C#实现的树数据结构的源代码,这对于学习和理解数据结构以及C#编程是非常有价值的。 树是一种非线性数据结构,由节点(也称为顶点)和边组成,每个节点可以有零个或多个子节点。在C#...

    比特数据结构课件-Lesson5-二叉树.pdf

    【二叉树】是数据结构中的重要组成部分,它是一种特殊的树结构,每个节点最多只有两个子节点,分别称为左子节点和右子节点。二叉树的概念有助于解决许多计算机科学中的问题,例如文件系统目录结构的表示、搜索算法的...

    数据结构-树的简介.pdf

    树的存储结构包括双亲数组表示法、孩子链表表示法、左孩子右兄弟表示法等。双亲数组表示法是一种存储表示树结构的方法,它通过一个一维数组来存储树中所有结点的信息及其双亲信息,数组中的每个元素代表一个结点,...

    数据结构-树的实现实验报告.pdf

    数据结构中的树是一种重要的非线性数据结构,它模拟了现实世界中许多组织关系,例如家族树、组织架构等。树形结构在计算机科学中有着广泛的应用,如编译器的语法分析、数据库的索引结构等。在这个实验报告中,我们将...

    数据结构树学习教案.pptx

    - **左孩子-右兄弟表示法**:每个节点包含其左孩子和右兄弟节点的引用。 4. **树的运算** - **遍历**:主要有前序遍历、中序遍历和后序遍历,用于访问树的所有节点。 - **线索二叉树**:在二叉树中加入线索,...

    专升本数据结构第六章 树.pdf

    在计算机科学中,树是一种重要的非线性数据结构,它能够有效地表示和处理具有层次关系的数据。在专升本数据结构的学习中,理解树的概念、性质和操作至关重要。本章主要涵盖以下几个方面: 1. **树的定义**: 树是...

    数据结构-二叉树.pptx

    此外,还有左孩子右兄弟表示法,其中每个节点的右兄弟是其父节点的下一个孩子,这种表示法在某些操作中简化了代码实现。 二叉树的基本特征是每个节点最多有两个子节点,这导致了一些独特的性质。例如,第i层的最大...

    数据结构树与二叉树的ppt

    首先,树是一种非线性的数据结构,以分支关系表示层次结构。在树中,有一个特殊的节点称为根节点,它没有前驱节点,而其他节点可以分为若干互不相交的子树,每个子树自身也是一棵树。树的特点是至少有一个节点(根...

    数据结构与STL树学习教案.pptx

    树的存储结构是指树在计算机中的表示方式,包括双亲表示法、孩子表示法、双亲孩子表示法、孩子兄弟表示法等。树的基本操作包括树的创建、树的遍历、树的查找、树的插入、树的删除等。 二叉树是特殊类型的树,具有...

    C常用数据结构的类数据成员定义整理.docx

    5. 双法表示树类(如孩子双亲表示树、孩子兄弟表示树): - `ElemType data`:节点的数据域。 - `int parent` 或 `LinkList&lt;int&gt;childLkList`:表示父节点或子节点的链接。 - `int parent` 或 `...

    《数据结构教程与题解》课本电子版

    ### 数据结构教程与题解 —— 树形结构章节知识点详解 #### 一、树形结构概述 **树形结构**是一种重要的非线性数据结构,用于描述数据元素之间的一对多逻辑关系。这种结构中的节点形成分支和层次关系,类似于自然...

Global site tag (gtag.js) - Google Analytics