1. 程式人生 > >線索二叉樹中查詢前驅和後繼的問題

線索二叉樹中查詢前驅和後繼的問題

線索二叉樹

結點結構定義如下:

若結點有左子樹,則LChild域仍指向其左孩子;
否則,LChild域指向其某種遍歷序列中的直接前驅結點。

若結點有右子樹,則RChild域仍指向其右孩子;
否則,RChild域指向其某種遍歷序列中的直接後繼結點。

Ltag
0: LChild域指示結點的左孩子
1: LChild域指示結點的遍歷前驅

Rtag
0: RChild域指示結點的右孩子
1: RChild域指示結點的遍歷後繼

線索二叉樹的結點結構:

線索二叉樹

二叉樹的中序線索化

void Inthread(BiTree root)
{   if(root!=NULL)
    {
        Inthread(root->LChild);/*線索化左子樹*/
if(root->LChild == NULL) { root->LChild = pre; root->Ltag = 1; /*置前驅線索*/ } if(root->RChild == NULL) { root->RChild = root; root->Rtag = 1; /*置後繼線索*/ } pre = root; /*記錄當前訪問結點,將成為下一個訪問節點的前驅*/
Inthread(root->LChild);/*線索化右子樹*/ } }

先序、後序線索化也類似。

線上索二叉樹中查詢前驅和後繼結點

線索二叉樹有三種類型,分別為先序、中序、後序。

利用建立的線索二叉樹找某個節點的前驅或者後繼,仍不能有效解決先序線索二叉樹找先序前驅和後序線索二叉樹找後序後繼。

每個節點中存著自己的值,左孩子或者直接前驅和右孩子或者直接後繼,我們從每個節點只能向下查詢來找直接前驅或者直接後繼,時間複雜度為O(n)。

若去遍歷該節點的祖先節點,也可以找到先序的直接前驅和後序的直接後繼,但是不建立線索二叉樹通過遍歷也可以找到它的直接前驅和直接後繼,這兩種情況就不用用線索二叉樹去考慮了。所以線索二叉樹不能有效解決先序線索二叉樹找先序前驅和後序線索二叉樹找後序後繼。

4種可行情況程式碼

/*先序線索二叉樹找後繼*/
BiThrTree PreNext(BiThrThee p)
{
    if(p->Rtag == 1)
        next = p->RChild;
    else if(p->LChild){
        next = p->LChild;
    }else{
        next = p->RChild;
    }
    return next;
}
/*中序線索二叉樹找前驅*/
BiThrTree InPre(BiThrThee p)
{
    if(p->Ltag == 1)
        pre = p->LChild;
    else{
        for(q=p->LChild;q->Rtag==0;q=q->RChild)
            pre = q;
    }
    return pre;
}
/*中序線索二叉樹找後繼*/
BiThrTree InNext(BiThrThee p)
{
    if(p->Rtag == 1)
        next = p->RChild;
    else{
        for(q=p->RChild;q->Ltag==0;q=q->LChild)
            next = q;
    }
    return next;
}
/*後序線索二叉樹找前驅*/
BiThrTree PostPre(BiThrThee p)
{
    if(p->Ltag == 1)
        pre = p->LChild;
    else if(p->RChild){
        pre = p->RChild;
    }else{
        pre = p->LChild;
    }
    return pre;
}