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

//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++环境,教程在前面有,这里插个链接

原文地址:https://www.cnblogs.com/1by1/p/10386374.html

时间: 2024-10-10 02:01:39

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

后序线索二叉树

1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 6 using namespace std; 7 8 struct TREE{ 9 int val; 10 TREE *ch[2]; 11 TREE *thread;//该节点的线索的下一个节点 12 TREE(){} 13 TREE(int val){ 14 this->val = v

二叉树的前序、中序和后序线索化

二叉树是一种非线性结构,遍历二叉树需要通过递归或者用栈辅助实现非递归的遍历. 用二叉树作为压缩存储结构时,取到一个结点,只能获取节点的左孩子和右孩子,不能直接得到结点的任一遍历序列的前驱或者后继.为了实现这种遍历,偶们利用二叉树中指向左右子树的空指针来存放结点的前驱和后继. 线索化二叉树思路: 当某一结点的左结点或结右点存在NULL时,则该结点的为空的子结点需要线索化. 在进行线索化时,结点的前驱指向前一个访问过的结点,故定义一个指针prev来保存前一个结点:结点的后继偶们并不知道,则对于未来的

【数据结构】 非递归前中后序遍历二叉树

数据结构学的递归了,深入了解后写一个三序非递归的版本. //测试数据:abd##eg##h##c#f## #include <cstdio> #include <iostream> typedef char ElemType; typedef struct Node { ElemType elem; struct Node *lchild,*rchild; }Node,*BiTree; typedef struct{ BiTree *base; BiTree *top; int s

【TOJ 1224】数据结构练习题――后序遍历二叉树

Description 给定一颗二叉树,要求输出二叉树的深度以及后序遍历二叉树得到的序列.本题假设二叉树的结点数不超过1000. Input 输入数据分为多组,第一行是测试数据的组数n,下面的n行分别代表一棵二叉树.每棵二叉树的结点均为正整数,数据为0代表当前结点为空,数据为-1代表二叉树数据输入结束,-1不作处理.二叉树的构造按照层次顺序(即第1层1个整数,第2层2个,第3层4个,第4层有8个......,如果某个结点不存在以0代替). Output 输出每棵二叉树的深度以及后序遍历二叉树得到

中序线索二叉树

虽说对于二叉树的遍历操作来说非递归法使用用户自定义的栈来代替递归使用时的系统栈,可以得到不小的效率提升,但将二叉树线索化时能将用户栈也省略掉进一步提高了效率. 对于二叉树的链表结构,n个结点的二叉树有n+1个空链域(每个叶节点都有两个空链域),而线索二叉树就把这些空链域有效的利用了起来,在一般的二叉树中,我们只知道每个结点的左右孩子,并不知道某个结点在某种遍历方式下的直接前驱和直接后继,如果能够知道前驱和后继信息,就可以把二叉树看作一个链表结构,从而可以像遍历链表那样来遍历二叉树,进而提高效率.

数据结构:中序线索二叉树

//所谓线索二叉树无非是为了让原本指向NULL的节点指向一个详细的 //已经存在的节点,逻辑上实现指针的无空指向的实现.以下是我中 //序线索二叉树的实现.还是把先序线索二叉树与后序线索分开来写吧. #include<iostream> using namespace std; template<typename Type> struct Node { Type data; bool rflags;//false为线. bool lflags; Node<Type> *

前序、中序、后序遍历二叉树

/*(1) 建立一棵含有n个结点的二叉树,采用二叉链表存储建立结点的结构体类型: 按照先序遍历法将二叉树的序列给出: 动态申请内存空间存储新结点: 建立结点间的关系:(2) 前序(或中序.后序)遍历该二叉树*/#include<stdio.h>#include<malloc.h> // char DataType;typedef struct Node{ char data; struct Node *Lchild; struct Node *Rchild;}BiTNode,*Bi

(树)根据中序后序构建二叉树

题目:根据中序和后序遍历构建二叉树 思路:利用递归加上分治的思想.先找到根节点的值,然后在根据中序遍历找到根节点的左右两边的值,然后在递归的处理左右两边的左右子树.这里的关键在于怎么处理递归的左右子树的范围,代码里面详细解释 代码: class Solution { public: TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) { vector<int>::size_t

已知先序后序构造二叉树

已知二叉树先序后序的基础上,可以构造出不唯一的二叉树集.主要思路如下: 先序遍历中刚遍历到的下一个节点是后序遍历中最后遍历的节点,所以可以将后序遍历拆分成两个子序列,从而进行递归构造. 例如 先序遍历为aebdc,后序遍历为bcdea. 首先可以确定根节点为a,在后序中找先序的下一个节点(也就是e),将原序列拆分成两部分,其左子树包含的元素有bcde,右子树为空. 接着在bcd中寻找先序中e的后一个元素即b的位置,将这个子序列又拆分成了b和cd两部分.如此递归下去就能得到一种可能的二叉树.