二叉线索树-创建中序二叉线索树、查找前驱、查找后继、按照前驱或后继遍历

#include <iostream>
#include <stack>
using namespace std;

struct BiThrNode
{
    int data;
    BiThrNode *left;
    BiThrNode *right;
    bool ltag;//0表示left指向左子,1表示left指向直接前驱
    bool rtag;
    //BiThrNode(int val,BiThrNode *l,BiThrNode *r,bool lt,bool rt):data(val),left(l),right(r),ltag(lt),rtag(rt){}
};

/*递归 建立二叉查找/搜索树*/
BiThrNode *CreateTree(BiThrNode *root, int val)
{
    if(!root)
    {
        root = (BiThrNode *)malloc(sizeof(BiThrNode));
        root->data = val;
        root->left = nullptr;
        root->right = nullptr;
        root->ltag = 0;
        root->rtag = 0;
    }
    if (val < root->data) root->left = CreateTree(root->left, val);
    if (val > root->data) root->right = CreateTree(root->right, val);
    return root;
}
/*普通中序遍历*/
void inorder(BiThrNode *root)
{
    if (!root) return;
    stack<BiThrNode *> s;
    BiThrNode *curr = root;
    while (curr || !s.empty())
    {
        if (curr)
        {
            s.push(curr);
            curr = curr->left;
        }
        else
        {
            cout << s.top()->data << " ";
            curr = s.top()->right;
            s.pop();
        }
    }
}
/*
1、创建中序二叉线索树
*/
BiThrNode *pre; //全局变量指向线索二叉树的前驱节点,第一个前驱是head
void intreading(BiThrNode *node)
{//除中间部分,就是递归中序遍历算法。这里把pre和node看做双向链表节点
    if (node)
    {
        intreading(node->left);
        if (!node->left)
        {
            node->ltag = 1;
            node->left = pre;
        }
        if (!pre->right)
        {
            pre->rtag = 1;
            pre->right = node;
        }
        pre = node;
        intreading(node->right);
    }
}
void inCreateBitree(BiThrNode *&head, BiThrNode *root)
{//构建头节点,左子指向二叉搜索树头节点,右子指向树最右子
    if (!root) return;
    head->ltag = 0;//调整头结点的左子
    head->left = root;
    head->rtag = 1;//调整头结点的左子
    head->right = head;//回指,经过intreading后才置为树最右子

    pre = head;//用于intreading
    intreading(root);//中序遍历线索化树,只差线索树最后一个节点和head关系

    pre->rtag = 1;//调节头结点右子
    pre->right = head;
    head->right = pre;
}
/*
2、中序二叉线索树 查找某节点前驱
【二叉查找树寻找前驱做对比】
*/
BiThrNode *inBiSearchPre(BiThrNode *node)
{
    BiThrNode *pre;
    pre = node->left;
    if (node->ltag != 1)//左子不是前驱
    {
        while (pre->rtag == 0)//找第一个没有右子的节点
            pre = pre->right;
    }
    return pre;
}
/*
3、中序二叉线索树 查找某节点后继
*/
BiThrNode *inBiSearchPost(BiThrNode *node)
{
    BiThrNode *post;
    post = node->right;
    if (node->rtag != 1)//右子不是前驱
    {
        while (post->ltag == 0)//找第一个没有左子的节点
            post = post->left;
    }
    return post;
}
/*
 4、根据前驱节点进行中序线索二叉树的遍历(倒序)
 */
void InOrderPre(BiThrNode *head)
{
    BiThrNode *p;
    p = head->right;//中序线索二叉树的最右子节点
    while (p != NULL && p != head)//like链表,根据线索遍历
    {
        cout << p->data << " ";
        p = inBiSearchPre(p);//根据线索,找到p的后继节点
    }
}
/*
 5、根据后继节点进行中序线索二叉树的遍历(正序)
 */
void InOrderPost(BiThrNode *head)
{
    BiThrNode *p;
    p = head->left;
    while (p->ltag != 1)//从二叉线索树头找到最左子
    {
        p = p->left;
    }
    while (p != NULL && p != head)//like链表,根据线索遍历
    {
        cout << p->data << " ";
        p = inBiSearchPost(p);//根据线索,找到p的后继节点
    }
}

int main()
{
    int t[] = { 4,2,5,1,3,6,7 };
    BiThrNode *root = nullptr;
    for (int i = 0; i < 7; i++)
        root = CreateTree(root, t[i]);
    cout << "中序遍历二叉查找树:";
    inorder(root);
    cout<< endl;

    BiThrNode *head = new BiThrNode;//二叉线索树头结点,指向树根
    inCreateBitree(head, root);//创建中序线索二叉树

    cout << "根据后继节点进行中序线索二叉树的遍历(正序):";
    InOrderPost(head);
    cout << endl;

    cout << "根据前驱节点进行中序线索二叉树的遍历(倒序):";
    InOrderPre(head);
    cout << endl;
}

原文地址:https://www.cnblogs.com/beixiaobei/p/10914255.html

时间: 2024-11-05 22:40:14

二叉线索树-创建中序二叉线索树、查找前驱、查找后继、按照前驱或后继遍历的相关文章

【数据结构】线索化二叉树中序线索化的递归写法和非递归写法

二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历.用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继. 为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息.所以引入了线索化二叉树.下面我们讲一下线索化二叉树中序线索化的两种实现方法: (1).递归实现中序线索化二叉树 首先我们先看一下线索化二叉树的结构 enum PointerTag{ THREAD, LINK 

[LeetCode] 285. Inorder Successor in BST 二叉搜索树中的中序后继节点

Given a binary search tree and a node in it, find the in-order successor of that node in the BST. Note: If the given node has no in-order successor in the tree, return null. 给一个二叉搜索树和它的一个节点,找出它的中序后继节点,如果没有返回null. 解法1: 用中序遍历二叉搜索树,当找到root.val = p.val的时

二叉树系列(二):已知中序遍历序列和后序遍历序列,求先序遍历序列

前面已经介绍过三种遍历方法的规则,为了大家看着方便,这里我们在重新介绍一遍: 1.先序遍历 (1)访问根结点: (2)先序遍历左子树: (3)先序遍历右子树.  2.中序遍历 (1)中序遍历左子树: (2)访问根结点: (3)中序遍历右子树. 3.后序遍历 (1)后序遍历左子树: (2)后序遍历右子树: (3)访问根结点. 知道了二叉树的三种遍历规则,只要有中序遍历序列和前后任一种遍历序列,我们就可以求出第三种遍历序列,今天我们研究的是已知中序和后序遍历序列,求先序遍历序列. 已知该二叉树的中序

数据结构例程——线索化二叉树(中序)

本文是数据结构基础系列(6):树和二叉树中第14课时线索二叉树的例程. #include <stdio.h> #include <malloc.h> #define MaxSize 100 typedef char ElemType; typedef struct node { ElemType data; int ltag,rtag; //增加的线索标记 struct node *lchild; struct node *rchild; } TBTNode; void Creat

数据结构已知后序和中序画出该树

已知二叉树后序遍历序列是DBCEFGHA,中序遍历序列EDCBAHFG,它的前序遍历的序列是?麻烦再画下这二叉树. 后续遍历的顺序是左右根,中序遍历的顺序是左根右 这点应该懂吧 由后续访问序列可以看出最后一个被访问的必定是这个树的根 而中序遍历的序列可以看出,一棵树当根确定后,在根前面被访问的是他的左子树,后边的是他的右子树元素 弄懂了上边两点就开始做题吧 由后序遍历序列是DBCEFGHA 为了方便,我写小写字母了啊 可以看出整棵树的根节点是a 再看中序遍历序列EDCBAHFG a是根节点 左子

树的中序遍历

中序遍历按照“左孩子-根结点-右孩子”的顺序进行访问. 1.递归实现 void inOrder(BinTree* root) { if(root!=NULL) { inOrder(root->lchild); cout<<root->data; inOrder(root->rchild); } } 2.非递归实现 对于任一结点P, 1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理: 2)若其左孩子为空,则取栈顶元素并进行出栈操作,访

数据结构已知先序和中序画出该树

这道题目很经典,具体如下: 已知遍历结果如下,试画出对应的二叉树: 前序:A B C E H F I J D G K 中序:A H E C I F J B D K G 解题要点: 1.前序.中序.后序--都针对中间那个节点而言(根节点也是中间的节点). 前序,指先遍历中间节点,然后左,然后右. 中序,指左--中--右. 后序,指右--中--左. 2.根据两种不同序列的遍历方法,便可画出二叉树. 解题答案如下:(对照着看会好理解这道题目一些的) 解题思路: 1.前序中序都首先找出A,推断出:A没有

[Swift]LeetCode285. 二叉搜索树中的中序后继节点 $ Inorder Successor in BST

Given a binary search tree and a node in it, find the in-order successor of that node in the BST. The successor of a node p is the node with the smallest key greater than p.val. Example 1: Input: root = [2,1,3], p = 1 Output: 2 Explanation: 1's in-or

[LeetCode] Inorder Successor in BST II 二叉搜索树中的中序后继节点之二

Given a binary search tree and a node in it, find the in-order successor of that node in the BST. The successor of a node p is the node with the smallest key greater than p.val. You will have direct access to the node but not to the root of the tree.