[三叉链表]利用三叉链表找后序线索二叉树的后继

Posted 1by1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[三叉链表]利用三叉链表找后序线索二叉树的后继相关的知识,希望对你有一定的参考价值。

//Three.h
#ifndef THREE_H
#define THREE_H
#include <iostream>
#include <string.h>
using namespace std;

typedef enum{Link, Thread} Tag;

typedef struct ThreeNode
{
    char data;
    struct ThreeNode *lChild, *rChild, *Parent;//采用三叉链表,增加一个指向双亲的结点
    Tag lTag, rTag;
}ThreeNode, *PThreeNode;

class Three
{
protected:
    PThreeNode root;
public:
    Three()//默认构造函数
    {
        root = NULL;
    }
    Three(PThreeNode r)//构造函数
    {
        root = r;
    }
    ~Three()//析构函数
    {
        PThreeNode temp = First();
        while(temp != root)
        {
            delete temp;
            temp = Next(temp);
        }
        delete root;
    }

    void CreateTree(PThreeNode &e, char TreeArray[], PThreeNode Par)//已知后序序列,创建树
    {
        static int count = strlen(TreeArray)-1;//这里我们反其道而行之,总最后一个开始,也就是根节点
        char ch = TreeArray[count--];//后序遍历的第一个字符一定为‘#‘,这样程序就不对了
        if(ch == #)
        {
            e = NULL;
        }
        else
        {
            e = new ThreeNode;
            e->data = ch;
            e->Parent = Par;
            e->lTag = Link;
            e->rTag = Link;
            CreateTree(e->rChild, TreeArray, e);
            CreateTree(e->lChild, TreeArray, e);
        }
    }
    void CreateTree(char TreeArray[])
    {
        CreateTree(root, TreeArray, NULL);
    }

    void Print(PThreeNode &e)//后序打印二叉树
    {
        if(e != NULL)
        {
            Print(e->lChild);
            Print(e->rChild);
            cout << e->data << "  ";
        }
    }
    void Print()
    {
        Print(root);
    }

    void ThreadPrint()//线索化,后序打印二叉树
    {
        PThreeNode temp = First();
        while(temp != root)
        {
            cout << temp->data << "  ";
            temp = Next(temp);
        }
        cout << temp->data;
    }

    PThreeNode Find(const char &ch) //查找结点
    {
        PThreeNode p = First();
        while (p != NULL && p->data != ch)
        {
            p = Next(p);
        }
        return p;
    }
    PThreeNode First() const//找到后序遍历的首位置
    {
        if (root == NULL)
            return  NULL;
        else 
        {
            PThreeNode p = root;
            while (p->lChild != NULL)
                p = p->lChild;
            return p;
        }
    }
    PThreeNode Next(PThreeNode &e)//返回结点的下一位置
    {
        PThreeNode temp = e;
        PThreeNode Par = temp->Parent;
        if(temp->rTag == Thread)
        {
            return temp->rChild;
        }
        else if(Par->rChild == temp)
        {
            return Par;
        }
        else if(root == e)
        {
            return root;
        }
        else 
        {
            temp = Par;
            while(temp->lChild != e || temp->lTag != Thread)
            {
                temp = temp->rChild;
                while(temp->lTag == Link)
                {
                    temp = temp->lChild;
                }
            }
            return temp;
        }
    }

    PThreeNode GetRoot() const//得到根节点
    {
        return root;
    }

    void ThreadTree(PThreeNode &e, PThreeNode &pre)//后序线索二叉树,pre用引用传递,使其能保存上次的值
    {
        if(e !=NULL )
        {
            ThreadTree(e->lChild, pre);
            ThreadTree(e->rChild, pre);

            if(e->lChild == NULL)
            {
                e->lChild = pre;
                e->lTag = Thread;
            }

            if(pre != NULL && pre->rChild == NULL)
            {
                pre->rChild = e;
                pre->rTag = Thread;
            }

            pre = e;
        }
    }

    void ThreadTree()//后序线索二叉树
    {
        PThreeNode temp = NULL;
        ThreadTree(root, temp);
    }

};

#endif

 

#include "Three.h"
#include <iostream>
using namespace std;

int main()
{
    char ch[] = {#,#,D,#,#,G,#,E,B,#,#,#,F,C,A};
    Three bt;
    PThreeNode p;

    bt.CreateTree(ch);
    cout << "后序遍历的顺序为:";
    bt.Print();
    cout << endl;

    bt.ThreadTree();
    cout << "线索化后,后序遍历的顺序为:";
    bt.ThreadPrint();
    cout << endl;
    
    p = bt.Find(A);//根节点为特殊情况
    if(p != bt.GetRoot())
    {
        p = bt.Next(p);
        cout << "该结点后继为:" << p->data << endl;
    }
    else
        cout << "该结点为线索树的最后一个元素,无后继!!!" << endl;
    
    system("pause");
    return 0;
}

 

用的自己借助sublime TEXT搭建的C++环境,教程在前面有,这里插个链接

以上是关于[三叉链表]利用三叉链表找后序线索二叉树的后继的主要内容,如果未能解决你的问题,请参考以下文章

超强二叉树解析.必收藏!(数组,链表实现,8种遍历方法,前,中,后序线索化二叉树及其遍历)---风之java

二叉树的线索化

线索二叉树

java实现线索化二叉树的前序中序后续的遍历(完整代码)

线索化二叉树

线索二叉树详解