树类的定义和遍历

实现树类的定义,结点的增删,以及先根,后根,层序周游遍历

#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;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值