【算法与数据结构】二叉树 中序线索

 

中序线索二叉树

/************************************************************************
线索二叉树
二叉树的节点有五部分构造
-----------------------------------------
| 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 << "创建头节点不成功\r\n"<<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 << "----------开始 递归先序创建二叉树----------\r\n";
    PBinaryTree pRoot = NULL;
    InitBinaryTree(pRoot);
    cout << "----------结束 递归先序创建二叉树----------\r\n\r\n";

    cout << "\r\n----------开始 中序线索二叉树---------------\r\n";
    PBinaryTree pNode = NULL;
    InOrderThreading(pNode, pRoot);
    cout << "\r\n----------结束 中序线索二叉树---------------\r\n";

    //InOrderTraverse(pRoot); 

    cout << "\r\n\r\n############开始 中序线索遍历二叉树###############\r\n";
    InOrderTraverse(pNode);
    cout << "\r\n#############结束 中序线索遍历二叉树################\r\n\r\n";

    return 0;
}

 

 

 

 

  

  

posted on 2014-05-18 13:19  崔好好  阅读(412)  评论(0编辑  收藏  举报

导航