zoukankan      html  css  js  c++  java
  • 【算法与数据结构】二叉树 中序线索

    中序线索二叉树

    /************************************************************************
    线索二叉树
    二叉树的节点有五部分构造
    -----------------------------------------
    | lChild | lTag | value | rTag | rChild |
    -----------------------------------------
    
    lChild = (lTag == 0 ? 左孩子指针 : 某种遍历的前驱节点)
    rChild = (rTag == 0 ? 右孩子指针 : 某种遍历的后继节点)   
    
    对二叉树通过某种遍历将其变为线索二叉树的过程成为二叉树的线索化。
    
    设置一个头结点,头结点的lChild指向根节点
    rChild指向遍历次序的最后一个节点
    遍历次序的第一个节点lChild指向头结点
    遍历次序的最后一个节点的最后一个节点
    
    ************************************************************************/
    #ifndef OVERFLOW_FOR_MALLOC 
    #define OVERFLOW_FOR_MALLOC   (-1)
    #endif
    
    typedef enum{Link = 0, Thread = 1 }ThreadEnum;
    
    typedef struct _tagBinaryTree
    {
        unsigned char value;
        struct _tagBinaryTree* left;
        struct _tagBinaryTree* right;
        ThreadEnum lTag;
        ThreadEnum rTag;
    }BinaryTree, *PBinaryTree;
    
    
    //访问节点
    void Visit(PBinaryTree pNode)
    {
        if (NULL != pNode) 
            cout << "节点的值为 "<<pNode->value<<endl;
    }
    //递归先序建立二叉树
    void InitBinaryTree(PBinaryTree& pNode)
    { 
        cout << "请输入节点的值,#表示NULL:";
        unsigned char chValue = 0;
        cin >> chValue;
        if ('#' == chValue)
        {
            pNode = NULL;
        }
        else
        {
            pNode = (PBinaryTree)(malloc(sizeof(BinaryTree)));
            if (NULL == pNode) exit(OVERFLOW_FOR_MALLOC);
        
            pNode->value = chValue;
            pNode->lTag = Link;
            pNode->rTag = Link;
            InitBinaryTree(pNode->left);
            InitBinaryTree(pNode->right);        
        } 
    }
    //递归中序线索化
    //p为根节点
    //pPreNode为一个辅助节点
    void InThreading(PBinaryTree& p, PBinaryTree& pPreNode)
    {
        if (p)
        {
            InThreading(p->left, pPreNode);
            if (! p->left)
            {
                p->lTag = Thread;
                p->left = pPreNode;
            }
            if (! pPreNode->right)
            {
                pPreNode->rTag = Thread;
                pPreNode->right = p;            
            }
            pPreNode = p;
            InThreading(p->right, pPreNode);
        } 
    }
    //中序线索二叉树, 为头结点申请空间,初始化头结点指针
    //中序线索化后
    //Thrt为头结点,T为二叉树的根节点
    void InOrderThreading(PBinaryTree& Thrt, PBinaryTree T)
    {
        if(NULL == T) return;
    
        Thrt = (PBinaryTree)(malloc(sizeof(BinaryTree)));    
        if(NULL == Thrt)      
        {
            cerr << "创建头节点不成功
    "<<endl; 
            return;
        }
        
        //初始化头结点,左指针为Link,指向根节点;右指针为Thread,回指.
        Thrt->lTag = Link;
        Thrt->rTag = Thread;
    
        Thrt->left = T;
        Thrt->right = Thrt;
    
        PBinaryTree pPreNode = Thrt; 
        InThreading(T, pPreNode);
        pPreNode->right = Thrt;
        pPreNode->rTag = Thread;
        Thrt->right = pPreNode;
    }
    //中序线索遍历二叉树
    //p为头结点,而非根节点
    void InOrderTraverse(PBinaryTree T)
    {
        //p为根节点
        PBinaryTree p = T->left;
        while (p != T)
        {
            //一直找到中序遍历的第一个节点
            while(p->lTag == Link) p = p->left;
            //并访问之
            Visit(p);
    
            //访问p的后继结点
            while(p->rTag == Thread && p->right != T)
            {
                p = p->right;
                Visit(p);
            }
            p = p->right;
        }
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        cout << "----------开始 递归先序创建二叉树----------
    ";
        PBinaryTree pRoot = NULL;
        InitBinaryTree(pRoot);
        cout << "----------结束 递归先序创建二叉树----------
    
    ";
    
        cout << "
    ----------开始 中序线索二叉树---------------
    ";
        PBinaryTree pNode = NULL;
        InOrderThreading(pNode, pRoot);
        cout << "
    ----------结束 中序线索二叉树---------------
    ";
    
        //InOrderTraverse(pRoot); 
    
        cout << "
    
    ############开始 中序线索遍历二叉树###############
    ";
        InOrderTraverse(pNode);
        cout << "
    #############结束 中序线索遍历二叉树################
    
    ";
    
        return 0;
    }

      

      

  • 相关阅读:
    oracle_深刻理解数据库的启动和关闭
    oracle_利用闪回功能恢复数据
    oracle_五千万数据插入测试
    java_eclipse_svn 与服务器同步时 ,忽略某类型文件和文件夹
    oracle_根据表名拼装语句
    crawler_网络爬虫之数据分析_httpwatcher
    113. Path Sum II (Tree; DFS)
    112. Path Sum (Tree; DFS)
    150. Evaluate Reverse Polish Notation (Stack)
    32. Longest Valid Parentheses (Stack; DP)
  • 原文地址:https://www.cnblogs.com/cuish/p/3735100.html
Copyright © 2011-2022 走看看