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


    #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;
    }
  • 相关阅读:
    解决页面报错: GEThttp://localhost:8080/favicon.ico 404 (Not Found)
    vs2019快捷键整理
    js保存图片至本地
    PHP输出方式的区别
    js运算精度问题
    Hadoop相关问题
    2015年10月5日 12:49:07
    Hive数据倾斜
    Hadoop错误日志
    使用maven开发MR
  • 原文地址:https://www.cnblogs.com/beixiaobei/p/10914255.html
Copyright © 2020-2023  润新知