1. 程式人生 > >二叉樹前驅後繼的查詢(這個容易理解)

二叉樹前驅後繼的查詢(這個容易理解)

轉自文庫

線索二叉樹的運算

1查詢某結點*p在指定次序下的前趨和後繼結點1)在中序線索二叉樹中,查詢結點*p的中序後繼結點  在中序線索二叉樹中,查詢結點*p的中序後繼結點分兩種情形:*p的右子樹空(p->rtagThread),則p->rchild為右線索,直接指向*p的中序後繼。  【例】下圖的中序線索二叉樹中,結點D的中序後繼是A



       
*p的右子樹非空(p->rtagLink),則*p的中序後繼必是其右子樹中第一個中序遍歷到的結點。也就是從*p的右孩子開始,沿該孩子的左鏈往下查詢,直至找到一個沒有左孩子的結點為止,該結點是*p的右子樹中

"最左下"的結點,即*P的中序後繼結點。  【例】上圖的中序線索二叉樹中:A的中序後繼是F,它有右孩子;F的中序後繼是H,它無右孩子;B的中序後繼是D,它是B的右孩子。  在中序線索二叉樹中求中序後繼結點的過程可【參見動畫演示】,具體演算法如下:BinThrNode*InorderSuccessor(BinThrNode *p)
      {//
在中序線索樹中找結點*p的中序後繼,設p非空
         BinThrNode *q

         if (p->rtag==Thread) //*p
的右子樹為空
              Return p->rchild
//返回右線索所指的中序後繼

         else{
              q=p->rchild
//*p的右孩子開始查詢
              while (q->ltag==Link)
                   q=q->lchild
//左子樹非空時,沿左鏈往下查詢
              return q
//q的左子樹為空時,它就是最左下結點
             }//end if
      }
   
該演算法的時間複雜度不超過樹的高度h,即O(h)

2)在中序線索二叉樹中查詢結點*p的中序前趨結點  中序是一種對稱序,故在中序線索二叉樹中查詢結點*p

的中序前趨結點與找中序後繼結點的方法完全對稱。具體情形如下:*p的左子樹為空,則p->1child為左線索,直接指向*p的中序前趨結點;  【例】上圖所示的中序線索二叉樹中,F結點的中序前趨結點是A
*p的左子樹非空,則從*p的左孩子出發,沿右指標鏈往下查詢,直到找到一個沒有右孩子的結點為止。該結點是*p的左子樹中"最右下"的結點,它是*p的左子樹中最後一箇中序遍歷到的結點,即*p的中序前趨結點。  【例】上圖所示中序線索二叉樹中,結點E左子樹非空,其中序前趨結點是I
  在中序線索二叉樹中求中序前趨結點的過程可【參見動畫演示】,具體演算法如下:
    BinThrNode *Inorderpre(BinThrNode *p)
      {//
在中序線索樹中找結點*p的中序前趨,設p非空
         BinThrNode *q

        if (p->ltag==Thread) //*p
的左子樹為空
              return p->lchild
//返回左線索所指的中序前趨
         else{
              q=p->lchild
//*p的左孩子開始查詢
              while (q->rtag==Link)
                   q=q->rchild
//右子樹非空時,沿右鏈往下查詢
              return q
//q的右子樹為空時,它就是最右下結點
             }//end if
      }
  由上述討論可知:對於非線索二叉樹,僅從*p出發無法找到其中序前趨(或中序後繼),而必須從根結點開始中序遍歷,才能找到*p的中序前趨(或中序後繼)。線索二叉樹中的線索使得查詢中序前趨和中序後繼變得簡單有效。

3在後序線索二叉樹中,查詢指定結點*p的後序前趨結點  在後序線索二叉樹中,查詢指定結點*p的後序前趨結點的具體規律是:*p的左子樹為空,則p->lchild是前趨線索,指示其後序前趨結點。   【例】在下圖所示的後序線索二叉樹中,H的後序前趨是BF的後序前趨是C


*p的左子樹非空,則p->lchild不是前趨線索。由於後序遍歷時,根是在遍歷其左右子樹之後被訪問的,故*p的後序前趨必是兩子樹中最後一個遍歷結點。  當*p的右子樹非空時,*p的右孩子必是其後序前趨  【例】在上圖所示的後序線索二叉樹中,A的後序前趨是E  當*p無右子樹時,*p的後序前趨必是其左孩子  【例】在上圖所示的後序線索二叉樹中,E的後序前趨是F

4在後序線索二叉樹中,查詢指定結點*p的後序後繼結點  具體的規律:*p是根,則*p是該二叉樹後序遍歷過程中最後一個訪問到的結點。*p的後序後繼為空*p是其雙親的右孩子,則*p的後序後繼結點就是其雙親結點  【例】上圖所示的後序線索二叉樹中,E的後序後繼是A*p是其雙親的左孩子,但*P無右兄弟,*p的後序後繼結點是其雙親結點  【例】上圖所示的後序線索二叉樹中,F的後序後繼是E*p是其雙親的左孩子,但*p有右兄弟,則*p的後序後繼是其雙親的右子樹中第一個後序遍歷到的結點,它是該子樹中"最左下的葉結點"
  【例】上圖所示的後序線索二叉樹中,B的後序後繼是雙親A的右子樹中最左下的葉結點H

注意:F是孩子樹中"最左下"結點,但它不是葉子。  由上述討論中可知:在後序線索樹中,僅從*p出發就能找到其後序前趨結點;要找*p的後序後繼結點,僅當*p的右子樹為空時,才能直接由*p的右線索p->rchild得到。否則必須知道*p的雙親結點才能找到其後序後繼。因此,如果線索二叉樹中的結點沒有指向其雙親結點的指標,就可能要從根開始進行後序遍歷才能找到結點*P的後序後繼。由此,線索對查詢指定結點的後序後繼並無多大幫助