实现树类的定义,结点的增删,以及先根,后根,层序周游遍历
#include <iostream>
#include <queue>
using namespace std;
template <class T> class Tree; //声明树类
template <class T>
class TreeNode {
friend class Tree<T>;
private:
T m_Value; //树结点的值
TreeNode<T>* pChild; //左子结点
TreeNode<T>* pSibling; //右兄弟结点
public:
TreeNode(const T& value); //拷贝构造函数
virtual ~TreeNode() {}; //析构函数
bool isLeaf(); //如果结点是叶,返回true
T Value(); //返回结点的值
TreeNode<T>* LeftMostChild(); //返回第一个左孩子
TreeNode<T>* RightSibling(); //返回右兄弟
void setValue(T&); //设置结点的值
void setChild(TreeNode<T>* pointer); //设置左孩子
void setSibling(TreeNode<T>* pointer); //设置右兄弟
void InsertFirst(TreeNode<T>* node); //以第一个左孩子身份插入结点
void InsertNext(TreeNode<T>* node); //以右兄弟的身份插入结点
};
template<class T>
TreeNode<T>::TreeNode(const T& value) { //拷贝构造函数
m_Value=value;
pChild=NULL;
pSibling=NULL;
}
template <class T>
bool TreeNode<T>::isLeaf() {
//如果结点是叶,返回true
if (pChild == NULL)
return true;
return false;
}
template<class T>
T TreeNode<T>::Value() { //返回结点的值
return m_Value;
}
template<class T>
TreeNode<T>* TreeNode<T>::LeftMostChild() { //返回第一个左孩子
return pChild;
}
template<class T>
TreeNode<T>* TreeNode<T>::RightSibling() { //返回右兄弟
return pSibling;
}
template <class T>
void TreeNode<T>::setValue(T& value) {
//设置结点的值
m_Value = value;
}
template<class T>
void TreeNode<T>::setChild(TreeNode<T>* pointer) { //设置左孩子
pChild=pointer;
}
template<class T>
void TreeNode<T>::setSibling(TreeNode<T>* pointer) { //设置右兄弟
pSibling=pointer;
}
template <class T>
void TreeNode<T>::InsertFirst(TreeNode<T>* node) {
//以第一个孩子的身份插入结点
if (pChild)
node->pSibling = pChild;
pChild = node;
}
template<class T>
void TreeNode<T>::InsertNext(TreeNode<T>* node) { //以右兄弟的身份插入结点
if(pSibling)
node->pSibling=pSibling;
pSibling=node;
}
template <class T>
class Tree {
private:
TreeNode<T>* root; //树根结点
void DestroyNodes(TreeNode<T>*root); //删除以root为根的子树
public:
Tree(); //构造函数
virtual ~Tree(); //析构函数
TreeNode<T>* getRoot(); //返回树中的根结点
void CreateRoot(const T& rootValue); //创建树中的根结点,使根结点元素的值为rootValue
bool isEmpty(); //判断是否为空树,如果是则返回true
TreeNode<T>* Parent(TreeNode<T>* current); //返回current结点的父结点
TreeNode<T>* PrevSibling(TreeNode<T>* current); //返回current结点的前一个邻居结点
void DeleteSubTree(TreeNode<T>* subroot); //删除以subroot为根的子树的所有结点
void RootFirstTraverse(TreeNode<T>* root); //先根深度优先周游树
void RootLastTraverse(TreeNode<T>* root); //后根深度优先周游树
void WidthTraverse(TreeNode<T>* root); //广度优先周游树
void Visit(T Value) { //访问
cout << Value;
};
};
template <class T>
Tree<T>::Tree() { //构造函数
root=NULL;
}
template <class T>
Tree<T>::~Tree() { //析构函数
while(root)
DeleteSubTree(root);
}
template <class T>
TreeNode<T>* Tree<T>::getRoot() { //返回树中的根结点
return root;
}
template <class T>
void Tree<T>::CreateRoot(const T& rootValue) {//创建树中的根结点,使根结点元素的值为rootValue
if(!root)
root=new TreeNode<T>(rootValue);
}
template <class T>
bool Tree<T>::isEmpty() { //判断是否为空树,如果是则返回true
if(root)
return false;
return true;
}
template <class T>
TreeNode<T>* Tree<T>::PrevSibling(TreeNode<T>* current) {//返回current结点的前一个邻居结点
using std::queue; //使用STL队列
queue<TreeNode<T>*> aQueue;
TreeNode<T>* pointer=root; //标识当前结点
TreeNode<T>* prev=NULL; //标识当前结点的前一个兄弟结点
//当前结点为空,树为空或所求结点为根结点时,返回NULL
if((current==NULL)||(pointer==NULL)||(current==root))
return NULL;
while(pointer) {
if(pointer==current)
return prev; //找到当前结点
aQueue.push(pointer);
prev=pointer;
pointer=pointer->pSibling; //沿当前结点右兄弟结点链寻找
}
while(!aQueue.empty()) {
prev=NULL;
pointer=aQueue.front();
aQueue.pop(); //出队列
pointer=pointer->LeftMostChild(); //下降到左子结点
while(pointer) {
if(pointer==current)
return prev;
aQueue.push(pointer);
prev=pointer;
pointer=pointer->pSibling; //沿当前结点右兄弟结点链寻找
}//end while
}//end while
return NULL;
}
template <class T>
TreeNode<T>* Tree<T>::Parent(TreeNode<T>* current) {
using std::queue; // 使用STL队列
queue<TreeNode<T>*> aQueue;
TreeNode<T>* pointer = root;
TreeNode<T>* upperlevelpointer = NULL; // 用于记录parent结点
if (current != NULL && pointer != current) {
while (pointer) { // 森林中所有根结点进队列
if (current == pointer)
return NULL; // 根的父结点指针为空,返回
aQueue.push(pointer);
pointer=pointer-> RightSibling();
}
while (!aQueue.empty()) {
pointer = aQueue.front(); // 取队列首结点指针
aQueue.pop(); // 出队列
upperlevelpointer = pointer; // 指向上一层的结点
pointer = pointer-> LeftMostChild(); // 指向当前结点的最左孩子
while (pointer) { // 当前结点的子结点进队列
if (current == pointer)
return upperlevelpointer; // 返回父结点指针
else {
aQueue.push(pointer);
pointer = pointer->RightSibling();
}
}//end while
}//end while
}//end if
return NULL;
}
template <class T>
void Tree<T>::DestroyNodes(TreeNode<T>* root) {
//删除以root为根的子树的所有结点
if (root) {
DestroyNodes(root->LeftMostChild()); //递归删除第一子树
DestroyNodes(root->RightSibling()); //递归删除其他子树
delete root; //删除根结点
}
}
template <class T>
void Tree<T>::DeleteSubTree(TreeNode<T>* subroot) {
// 删除以subroot为根的子树的所有结点
if (subroot == NULL) return;
TreeNode<T>* pointer = Parent (subroot); // 找subroot的父结点
if (pointer == NULL) // subroot就是森林第一个树根
root = subroot->RightSibling();
else if (pointer-> LeftMostChild() == subroot) // subroot为最左子结点的情况
pointer->setChild(subroot->RightSibling());
else { // subroot有左兄弟
pointer = pointer-> LeftMostChild(); // 下降到最左兄弟
while (pointer-> RightSibling() != subroot) // 顺右链找到直接左兄弟
pointer = pointer ->RightSibling();
pointer->setSibling(subroot->RightSibling());
}
subroot->setSibling(NULL);
DestroyNodes(subroot);
}
//树的深度、广度周游算法
template <class T>
void Tree<T>::RootFirstTraverse(TreeNode<T>* root) { //先根深度优先周游树
while (NULL != root) {
Visit(root->Value()); //访问当前结点
RootFirstTraverse(root->LeftMostChild()); //周游头一棵树树根的子树
root = root->RightSibling(); //周游其他的树
}
}
template <class T>
void Tree<T>::RootLastTraverse(TreeNode<T>* root) { //后根深度优先周游树
while (NULL != root) {
RootLastTraverse(root->LeftMostChild()); //周游头一棵树树根的子树
Visit(root->Value()); //访问当前结点
root = root->RightSibling(); //周游其他的树
}
}
template <class T>
void Tree<T>::WidthTraverse(TreeNode<T>* root) { // 广度优先周游树
using std::queue; // 使用STL队列
queue<TreeNode<T>*> aQueue;
TreeNode<T>* pointer = root; // 根作为当前结点
while (pointer) {
aQueue.push(pointer); // 当前结点进入队列
pointer = pointer->RightSibling(); // 指向当前结点的右兄弟
}//end while
while (!aQueue.empty()) {
pointer = aQueue.front(); // 取队列首结点指针
aQueue.pop(); // 出队列
Visit(pointer->Value()); // 访问当前结点
pointer = pointer-> LeftMostChild(); // 指向当前结点的最左孩子
while (pointer) { // 当前结点的子结点进队列
aQueue.push(pointer);
pointer = pointer->RightSibling();
}
}//end while
}
// 函数功能:周游树,在这里只列举一种(先根次序)
void Traverse(Tree<char> *tree)
{
cout << "FirstRoot traverse: ";
tree->RootFirstTraverse(tree->getRoot()); // 先根深度优先周游
cout << endl;
cout << "LastRoot traverse: ";
tree->RootLastTraverse(tree->getRoot()); // 后根深度
cout << endl;
cout << "Width traverse : ";
tree->WidthTraverse(tree->getRoot()); // 广度遍历
cout << endl << endl;
}
int main()
{
//建树
Tree<char> aTree;
aTree.CreateRoot('A');
TreeNode<char> *f = new TreeNode<char>('F');
TreeNode<char> *e = new TreeNode<char>('E');
TreeNode<char> *d = new TreeNode<char>('D');
TreeNode<char> *c = new TreeNode<char>('C');
TreeNode<char> *b = new TreeNode<char>('B');
e->setSibling(f);
c->setSibling(d);
c->setChild(e);
b->setSibling(c);
aTree.getRoot()->setChild(b);
TreeNode<char> *x = new TreeNode<char>('X');
TreeNode<char> *y = new TreeNode<char>('Y');
TreeNode<char> *z = new TreeNode<char>('Z');
aTree.getRoot()->setSibling(x);
x->setChild(y);
y->setSibling(z);
//显示树的结构
cout << " A X \n";
cout << " / | \\ / \\ \n";
cout << " B C D Y Z \n";
cout << " / \\ \n";
cout << " E F \n";
cout << "\n";
//判断树是否为空
aTree.isEmpty();
//周游树
cout << "周游树:\n";
Traverse(&aTree);
// 结果,先根:ABCEFDXYZ,后根:BEFCDAYZX,层序:AXBCDYZEF
//e结点插入第一个孩子G
cout << "e结点插入第一个孩子G的结果:\n";
TreeNode<char> *g = new TreeNode<char>('G');
e->InsertFirst(g);
//周游树
Traverse(&aTree);
// 结果,先根:ABCEGFDXYZ,后根:BGEFCDAYZX,层序:AXBCDYZEFG
//e结点以第一个兄弟的身份插入H
cout << "e结点以第一个兄弟的身份插入H的结果:\n";
TreeNode<char> *h = new TreeNode<char>('H');
e->InsertNext(h);
//周游树
Traverse(&aTree);
// 结果,先根:ABCEGHFDXYZ,后根:BGEHFCDAYZX,层序:AXBCDYZEHFG
//获得C的父结点
cout << "获得C的父结点: ";
aTree.Visit(aTree.Parent(c)->Value());
cout << endl;
//获得H的上一个兄弟结点
cout << "获得H的上一个兄弟结点: ";
aTree.Visit(aTree.PrevSibling(h)->Value());
cout << endl;
// aTree.Visit(aTree.PrevSibling(e)->Value());
// cout << endl;
//求父结点
cout<<"E的父结点:";
aTree.Visit(aTree.Parent(e)->Value());
cout<<endl;
cout<<"D的父结点:";
aTree.Visit(aTree.Parent(d)->Value());
cout<<endl;
cout<<"F的父结点:";
aTree.Visit(aTree.Parent(f)->Value());
cout<<endl;
cout<<"Z的父结点:";
aTree.Visit(aTree.Parent(z)->Value());
cout<<endl;
cout<<"X的父结点:";
if (aTree.Parent(x) == NULL)
cout<< "Parent is NULL!" << endl;
//删除根为E的子树
cout << "删除E子树:" << endl;
aTree.DeleteSubTree(e);
Traverse(&aTree);
//删除根为C的子树
cout << "删除C子树:" << endl;
aTree.DeleteSubTree(c);
Traverse(&aTree);
// 结果,先根:ABDXYZ,后根:BDAYZX,层序:AXBDYZ
return 0;
}