1. 程式人生 > >c++二叉樹的中序線索連結串列

c++二叉樹的中序線索連結串列

<div class="para" label-module="para">建立線索二叉樹,或者說對二叉樹線索化,實質上就是遍歷一棵二叉樹。在遍歷過程中,訪問結點的操作是檢查當前的左,右指標域是否為空,將它們改為指向前驅結點或後續結點的線索。為實現這一過程,設指標pre始終指向剛剛訪問的結點,即若指標p指向當前結點,則pre指向它的前驅,以便設線索。</div><div class="para" label-module="para"> </div><div class="para" label-module="para"><img src="https://img-blog.csdn.net/20161018143644296?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></div><div class="para" label-module="para"> </div>
#include <iostream>
using namespace std;

enum flag {Child,Thread};//child為0,thread為1

struct ThrNode
{
    char data;
    ThrNode *lchild,*rchild;
    flag ltag,rtag;
};

class InThrBiTree
{
public:
    InThrBiTree();
    ThrNode *Next(ThrNode *p);
    void InOrder();
private:
    ThrNode *root,*p,*q;
    ThrNode *Creat(ThrNode *bt);
    void ThrBiTree(ThrNode *bt);
};

ThrNode *pre=NULL;//定義pre(前驅)為空

ThrNode *InThrBiTree::Creat(ThrNode *bt)
{
    char ch;
    cin>>ch;
    if(ch=='#')bt=NULL;
    else
    {
        bt=new ThrNode;
        bt->data=ch;
        bt->ltag=Child;
        bt->rtag=Child;
        bt->lchild=Creat(bt->lchild);
        bt->rchild=Creat(bt->rchild);
    }
    return bt;
}

void InThrBiTree::ThrBiTree(ThrNode *bt)//中序線索化連結串列演算法
{
    if(bt!=NULL)
    {
        if(bt->ltag==Child)//左線索為0,即有左孩子時,繼續遞迴
            ThrBiTree(bt->lchild);
        if(bt->lchild==NULL)//直到左孩子為空,即左線索為1時
        {
            bt->ltag=Thread;
            bt->lchild=pre;//pre初值為空
        }
        if(bt->rchild==NULL)//若右孩子為空,即右線索為1時
            bt->rtag=Thread;
        if(pre!=NULL&&pre->rtag==Thread)//若前驅非空且前驅的右線索為1(沒有右孩子)時
            pre->rchild=bt;//前驅的右孩子就為bt
        pre=bt;//令bt為新的pre
        if(bt->rtag==Child)//若左線索為0,即左孩子存在時,繼續遞迴
            ThrBiTree(bt->rchild);
    }
}

InThrBiTree::InThrBiTree()
{
    root=Creat(root);
    ThrBiTree(root);//建立線索
}

ThrNode *InThrBiTree::Next(ThrNode *p)//查詢後繼演算法
{
    q=new ThrNode;
    if(p->rtag==Thread)//若標誌為1,即沒有右孩子
        q=p->rchild;//可以直接得到後繼結點
    else
    {
        q=p->rchild;
        while(q->ltag==Child)//否則一直尋找直到左線索為0,即有左孩子時
        {
            q=q->lchild;   //得到後繼
        }
    }
    return q;//返回後繼結點(指標)
}

void InThrBiTree::InOrder()
{
    if(root==NULL)return;
    p=root;
    while(p->ltag==Child)
    {
        p=p->lchild;
    }
    cout<<p->ltag<<" "<<p->data<<" "<<p->rtag<<endl;
    while(p->rchild!=NULL)
    {
        p=Next(p);
        cout<<p->ltag<<" "<<p->data<<" "<<p->rtag<<endl;
    }
}

int main()
{
    InThrBiTree b;
    b.InOrder();
    return 0;
}