鹰击长空

此去经年,谁许我一纸繁华

二叉树的中序遍历线索化

理论基础

在二叉树的二叉链表表示实现的时候,当以二叉树作为存储结构时,只能找到节点的左右孩子信息,不能直接得到结点在任一序列中的前驱和后继信息,只有在遍历过程中才能得到这种信息。我们知道,在n个结点的二叉链表栈必定存在n+1个空链域,因此,可以利用这些空链域来存放这些结点信息。所以作如下规定:若结点右左子树,则其lchild域指向其左孩子,否则令lchild域指向其前驱;若结点有右子树,其rchild域指向其右孩子,否则指向其后继。以这种结构构成的二叉链表叫做线索链表。

定义的二叉树数据结构(C++)

template<typename T> struct BNode
{
    T m_data;
    BNode<T>* rchild;
    BNode<T>* lchild;
    BNode<T>* parent;
    int ltag;
    int rtag;
    BNode(T data=0):m_data(data),rchild(NULL),lchild(NULL),parent(NULL),ltag(0),rtag(0){}
};
template<typename T> struct BTree
{
    BNode<T>* m_root;
    BNode<T>* index;
    BNode<T>* pre;
    T m_data;
    BTree(BNode<T>* root=NULL,T data=0):m_root(root),m_data(data),pre(NULL){}
}

二叉树的中序遍历线索化

  • 中序递归遍历的思想先线索左孩子,然后是根节点,最后是右孩子
void thread(BNode<T>* root)//将一个二叉树节点添加线索
{
    if(root==NULL)
    {
        return;
    }
    thread(root->lchild);
    if(root->lchild==NULL)
    {
        root->lchild=pre;
        root->ltag=1;
    }
    if(pre->rchild==NULL)
    {
        pre->rchild=root;
        pre->rtag=1;
    }
    pre=root;
    thread(root->rchild);
}
void create_thread()//将一个二叉树线索化
{
    index=new BNode<T>();
    index->rtag=1;
    index->ltag=0;
    if(m_root==NULL)
    {
        index->lchild=index;
        return;
    }
    index->lchild=m_root;
    pre=index;
    thread(m_root);
    pre->rchild=index;
    pre->rtag=1;
    index->rchild=pre;
    std::cout<<"index tree create"<<std::endl;
    std::cout<<"index lchild--> root"<<index->lchild->m_data<<std::endl;
    std::cout<<"index rchild--> tree last node"<<index->rchild->m_data<<std::endl;
}

中序线索顺序和逆序遍历二叉树

  • 顺序遍历
void index_visit()//中序顺序线索遍历二叉树
{
    BNode<T>* start=index->lchild;
    while(start!=index)
    {
        while(start->ltag==0)
        {
            start=start->lchild;
        }
        std::cout<<start->m_data<<" ";
        while(start->rtag==1&&start->rchild!=index)
        {
            start=start->rchild;
            std::cout<<start->m_data<<" ";
        }
        start=start->rchild;// 有右孩子的节点
    }
    std::cout<<std::endl;
}
  • 逆序遍历
void index_rvisit()//中序逆序线索遍历二叉树
{
    BNode<T>* end=index->rchild;
    while(end!=index)
    {
        while(end->rtag==0)
        {
            end=end->rchild;
        }
        std::cout<<end->m_data<<" ";
        while(end->ltag==1&&end->lchild!=index)//有前驱的节点
        {
            end=end->lchild;
            std::cout<<end->m_data<<" ";
        }
        end=end->lchild;//有左孩子的节点
    }
    std::cout<<std::endl;
}
阅读更多
个人分类: Linux-C++
博主设置当前文章不允许评论。

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭