树类的定义和遍历

来源:互联网 发布:东方财富网 数据 编辑:程序博客网 时间:2024/06/05 22:57

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

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

0 0
原创粉丝点击