# 数据结构（十三）——树

## 二、树的抽象实现

### 1、树的抽象实现

``````template <typename T>
class Tree:public Object
{
protected:
TreeNode<T>* m_root;//根结点
public:
Tree(){m_root = NULL;}
//插入结点
virtual bool insert(TreeNode<T>* node) = 0;
virtual bool insert(const T& value, TreeNode<T>* parent) = 0;
//删除结点
virtual SharedPointer< Tree<T> > remove(const T& value) = 0;
virtual SharedPointer< Tree<T> > remove(TreeNode<T>* node) = 0;
//查找结点
virtual TreeNode<T>* find(const T& value)const = 0;
virtual TreeNode<T>* find(TreeNode<T>* node)const = 0;
//根结点访问函数
virtual TreeNode<T>* root()const = 0;
//树的度访问函数
virtual int degree()const = 0;
//树的高度访问函数
virtual int height()const = 0;
//树的结点数目访问函数
virtual int count()const = 0;
//清空树
virtual void clear() = 0;
};``````

### 2、树结点的抽象实现

``````template <typename T>
class TreeNode:public Object
{
public:
T value;
TreeNode<T>* parent;
TreeNode()
{
parent = NULL;
}
virtual ~TreeNode() = 0;
};
template <typename T>
TreeNode<T>::~TreeNode()
{
}``````

## 三、树的操作

### 1、树和树结点的存储结构实现

GTreeNode能够包含任意多个指向后继结点的指针。

``````template <typename T>
class GTreeNode:public TreeNode<T>
{
protected:
};
GTree为通用树结构，每个结点可以存在多个后继结点。
template <typename T>
class GTree:public Tree<T>
{
public:
};``````

### 2、树中结点的查找

A、基于数据元素值的查找

``````GTreeNode<T>* find(GTreeNode<T>* node, const T& value)const
{
GTreeNode<T>* ret = NULL;
if(node != NULL)
{
//如果根结点的就是目标结点
if(node->value == value)
{
ret =  node;
}
else
{
//遍历根节点的子结点
for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
{
//对每个子子结点进行查找
ret = find(node->m_children.current(), value);
}
}
}
return ret;
}

//查找结点
virtual GTreeNode<T>* find(const T& value)const
{
return find(root(), value);
}``````

B、基于树中结点的查找

`````` GTreeNode<T>* find(GTreeNode<T>* node, GTreeNode<T>* obj)const
{
GTreeNode<T>* ret = NULL;
//根结点为目标结点
if(node == obj)
{
ret =  node;
}
else
{
if(node != NULL)
{
//遍历子结点
for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
{
ret = find(node->m_children.current(), obj);
}
}
}
return ret;
}

virtual GTreeNode<T>* find(TreeNode<T>* node)const
{
return find(root(), dynamic_cast<GTreeNode<T>*>(node));
}``````

### 3、树中结点的插入

A、插入结点

``````bool insert(TreeNode<T>* node)
{
bool ret = true;
if(node != NULL)
{
//树为空，插入结点为根结点
if(this->m_root == NULL)
{
node->parent = NULL;
this->m_root = node;
}
else
{
//找到插入结点的父结点
GTreeNode<T>* np = find(node->parent);
if(np != NULL)
{
GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
//如果子结点中无该结点，插入结点
if(np->m_children.find(n) < 0)
{
ret = np->m_children.insert(n);
}
}
else
{
THROW_EXCEPTION(InvalidOperationException, "Invalid node...");
}
}
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Parameter is invalid...");
}
return ret;
}``````

B、插入数据元素

``````bool insert(const T& value, TreeNode<T>* parent)
{
bool ret = true;
GTreeNode<T>* node = GTreeNode<T>::NewNode();
if(node != NULL)
{
node->value = value;
node->parent = parent;
insert(node);
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
}
return ret;
}``````

### 4、树中结点的清除

A、GTreeNode类中增加保护的堆空间标识成员m_flag
B、重载GTreeNode的operrator new操作符，声明为保护
C、提供工厂方法NewNode（），在工厂方法中创建堆空间的结点，并将m_flag标识置为true。

``````template <typename T>
class GTreeNode:public TreeNode<T>
{
protected:
bool m_flag;//堆空间标识
//重载new操作符，声明为保护
void* operator new(unsigned int size)throw()
{
return Object::operator new(size);
}

public:
GTreeNode()
{
//栈上分配的空间标识为false
m_flag = false;
}
//工厂方法，创建堆空间的结点
static GTreeNode<T>* NewNode()
{
GTreeNode<T>* ret = new GTreeNode<T>();
if(ret != NULL)
{
//堆空间的结点标识为true
ret->m_flag = true;
}
return ret;
}
//堆空间结点标识访问函数
bool flag()const
{
return m_flag;
}
};

void free(GTreeNode<T>* node)
{
if(node != NULL)
{
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
free(node->m_children.current());
}
//如果结点存储在堆空间
if(node->flag())
delete node;//释放
}
}

void clear()
{
free(root());
this->m_root = NULL;
}``````

### 5、树中结点的删除

``````void remove(GTreeNode<T>* node, GTree<T>*& ret)
{
ret = new GTree<T>();
if(ret != NULL)
{
//如果删除的结点是根结点
if(root() == node)
{
this->m_root = NULL;
}
else
{
//获取删除结点的父结点的子结点链表
//从链表中删除结点
child.remove(child.find(node));
//结点的父结点置NULL
node->parent = NULL;
}
//将删除结点赋值给创建的树ret的根结点
ret->m_root = node;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
}
}``````

A、基于删除数据元素值删除结点

`````` SharedPointer<Tree<T>> remove(const T& value)
{
GTree<T>* ret = NULL;
//找到结点
GTreeNode<T>* node = find(value);
if(node != NULL)
{
remove(node, ret);
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
}
return ret;
}``````

B、基于结点删除

`````` SharedPointer<Tree<T>> remove(TreeNode<T>* node)
{
GTree<T>* ret = NULL;
node = find(node);
if(node != NULL)
{
remove(dynamic_cast<GTreeNode<T>*>(node), ret);
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
}
return ret;
}``````

### 6、树中结点的属性操作

A、树中结点的数量

``````int count(GTreeNode<T>* node) const
{
int ret = 0;
if(node != NULL)
{
ret = 1;//根结点
//遍历根节点的子结点
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
ret += count(node->m_children.current());
}
}
return ret;
}
//树的结点数目访问函数
int count()const
{
count(root());
}``````

B、树的度

``````int degree(GTreeNode<T>* node) const
{
int ret = 0;
if(node != NULL)
{
//结点的子结点的数量
ret = node->m_children.length();
//遍历子结点
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
int d = degree(node->m_children.current());
if(ret < d)
{
ret = d;
}
}
}
return ret;
}

//树的度访问函数
int degree()const
{
return degree(root());
}``````

C、树的高度

``````int height(GTreeNode<T>* node)const
{
int ret = 0;
if(node != NULL)
{
//遍历子结点
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
//当前结点的高度
int h = height(node->m_children.current());
if(ret < h)
{
ret = h;
}
}
ret = ret + 1;
}
return ret;
}
//树的高度访问函数
int height()const
{
height(root());
}``````

### 7、树中结点的遍历

A、在树中定义一个游标（GTreeNode<T>* node）
B、遍历开始前将游标指向根结点
C、获取游标指向的数据元素
D、通过结点中的m_children成员移动游标

`````` bool begin()
{
bool ret = (root() != NULL);
if(ret)
{
//清空队列
m_queue.clear();
//根节点加入队列
}
return ret;
}``````

`````` bool end()
{
return (m_queue.length() == 0);
}``````

`````` bool next()
{
bool ret = (m_queue.length() > 0);
if(ret)
{
GTreeNode<T>* node = m_queue.front();
m_queue.remove();//队头元素出队
//将队头元素的子结点入队
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
}
}
return ret;
}``````

``````T current()
{
if(!end())
{
return m_queue.front()->value;
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No value at current Node...");
}
}``````

## 四、通用树结构的实现

### 1、通用树节点的实现

`````` template <typename T>
class GTreeNode:public TreeNode<T>
{
protected:
bool m_flag;//堆空间标识
//重载new操作符，声明为保护
void* operator new(unsigned int size)throw()
{
return Object::operator new(size);
}
GTreeNode(const GTreeNode<T>& other);
GTreeNode<T>& operator = (const GTreeNode<T>& other);

public:
GTreeNode()
{
//栈上分配的空间标识为false
m_flag = false;
}
//工厂方法，创建堆空间的结点
static GTreeNode<T>* NewNode()
{
GTreeNode<T>* ret = new GTreeNode<T>();
if(ret != NULL)
{
//堆空间的结点标识为true
ret->m_flag = true;
}
return ret;
}
//堆空间结点标识访问函数
bool flag()const
{
return m_flag;
}
};``````

### 2、通用树的实现

`````` template <typename T>
class GTree:public Tree<T>
{
protected:
GTree(const GTree<T>& other);
GTree<T>& operator=(const GTree<T>& other);
GTreeNode<T>* find(GTreeNode<T>* node, const T& value)const
{
GTreeNode<T>* ret = NULL;
if(node != NULL)
{
//如果根结点的就是目标结点
if(node->value == value)
{
ret =  node;
}
else
{
//遍历根节点的子结点
for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
{
//对每个子子结点进行查找
ret = find(node->m_children.current(), value);
}
}
}
return ret;
}
GTreeNode<T>* find(GTreeNode<T>* node, GTreeNode<T>* obj)const
{
GTreeNode<T>* ret = NULL;
//根结点为目标结点
if(node == obj)
{
ret =  node;
}
else
{
if(node != NULL)
{
//遍历子结点
for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
{
ret = find(node->m_children.current(), obj);
}
}
}
return ret;
}

void free(GTreeNode<T>* node)
{
if(node != NULL)
{
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
free(node->m_children.current());
}
//如果结点存储在堆空间
if(node->flag())
delete node;//释放
}
}

void remove(GTreeNode<T>* node, GTree<T>*& ret)
{
ret = new GTree<T>();
if(ret != NULL)
{
//如果删除的结点是根结点
if(root() == node)
{
this->m_root = NULL;
}
else
{
//获取删除结点的父结点的子结点链表
//从链表中删除结点
child.remove(child.find(node));
//结点的父结点置NULL
node->parent = NULL;
}
//将删除结点赋值给创建的树ret的根结点
ret->m_root = node;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
}
}

int count(GTreeNode<T>* node) const
{
int ret = 0;
if(node != NULL)
{
ret = 1;//根结点
//遍历根节点的子结点
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
ret += count(node->m_children.current());
}
}
return ret;
}

int height(GTreeNode<T>* node)const
{
int ret = 0;
if(node != NULL)
{
//遍历子结点
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
//当前结点的高度
int h = height(node->m_children.current());
if(ret < h)
{
ret = h;
}
}
ret = ret + 1;
}
return ret;
}

int degree(GTreeNode<T>* node) const
{
int ret = 0;
if(node != NULL)
{
//结点的子结点的数量
ret = node->m_children.length();
//遍历子结点
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
int d = degree(node->m_children.current());
if(ret < d)
{
ret = d;
}
}
}
return ret;
}
public:
GTree()
{

}
//插入结点
bool insert(TreeNode<T>* node)
{
bool ret = true;
if(node != NULL)
{
//树为空，插入结点为根结点
if(this->m_root == NULL)
{
node->parent = NULL;
this->m_root = node;
}
else
{
//找到插入结点的父结点
GTreeNode<T>* np = find(node->parent);
if(np != NULL)
{
GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
//如果子结点中无该结点，插入结点
if(np->m_children.find(n) < 0)
{
ret = np->m_children.insert(n);
}
}
else
{
THROW_EXCEPTION(InvalidOperationException, "Invalid node...");
}
}
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Parameter is invalid...");
}
return ret;
}
bool insert(const T& value, TreeNode<T>* parent)
{
bool ret = true;
GTreeNode<T>* node = GTreeNode<T>::NewNode();
if(node != NULL)
{
node->value = value;
node->parent = parent;
insert(node);
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
}
return ret;
}
//删除结点
SharedPointer<Tree<T>> remove(const T& value)
{
GTree<T>* ret = NULL;
//找到结点
GTreeNode<T>* node = find(value);
if(node != NULL)
{
remove(node, ret);
m_queue.clear();
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
}
return ret;
}

SharedPointer<Tree<T>> remove(TreeNode<T>* node)
{
GTree<T>* ret = NULL;
node = find(node);
if(node != NULL)
{
remove(dynamic_cast<GTreeNode<T>*>(node), ret);
m_queue.clear();
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
}
return ret;
}
//查找结点
GTreeNode<T>* find(const T& value)const
{
return find(root(), value);
}
GTreeNode<T>* find(TreeNode<T>* node)const
{
return find(root(), dynamic_cast<GTreeNode<T>*>(node));
}
//根结点访问函数
GTreeNode<T>* root()const
{
return dynamic_cast<GTreeNode<T>*>(this->m_root);
}
//树的度访问函数
int degree()const
{
return degree(root());
}
//树的高度访问函数
int height()const
{
height(root());
}
//树的结点数目访问函数
int count()const
{
count(root());
}
//清空树
void clear()
{
free(root());
this->m_root = NULL;
}

bool begin()
{
bool ret = (root() != NULL);
if(ret)
{
//清空队列
m_queue.clear();
//根节点加入队列
}
return ret;
}

bool end()
{
return (m_queue.length() == 0);
}

bool next()
{
bool ret = (m_queue.length() > 0);
if(ret)
{
GTreeNode<T>* node = m_queue.front();
m_queue.remove();//队头元素出队
//将队头元素的子结点入队
for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
{
}
}
return ret;
}

T current()
{
if(!end())
{
return m_queue.front()->value;
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No value at current Node...");
}
}
virtual ~GTree()
{
clear();
}
};``````