zoukankan      html  css  js  c++  java
  • 二叉线索树-创建中序二叉线索树、查找前驱、查找后继、按照前驱或后继遍历

    #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;
    }
  • 相关阅读:
    2018年2月1日学习总结
    2018年1月31日学习总结
    创建oracle数据库表空间和用户
    广播权限声明
    广播接收器
    Android的屏幕限定符
    hibernate学习笔记(3)hibernate常用配置以及session对象
    hibernate学习笔记(2)持久化类测试
    hibernate学习笔记(1)基础配置与jar包
    struts2学习笔记(5)拦截器
  • 原文地址:https://www.cnblogs.com/beixiaobei/p/10914255.html
Copyright © 2011-2022 走看看