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

Posted beixiaobei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉线索树-创建中序二叉线索树查找前驱查找后继按照前驱或后继遍历相关的知识,希望对你有一定的参考价值。

 

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

 

以上是关于二叉线索树-创建中序二叉线索树查找前驱查找后继按照前驱或后继遍历的主要内容,如果未能解决你的问题,请参考以下文章

王道数据结构与算法树(八——2)

数据结构 | 线索二叉树2 | 中序线索二叉树的构造(计算机408统考)

线索二叉树详解

线索二叉树--二叉树线索化

C#数据结构-线索化二叉树

二叉线索树