6 5二叉樹遍歷演算法基於棧的遞迴消除

2021-10-06 19:28:11 字數 2296 閱讀 4158

二叉樹的遍歷問題遞迴的問題無法直接轉換成迴圈,所以需要採用工作棧消 除遞迴。工作棧提供一種控制結構,當遞迴演算法進層時需要將資訊保留;當遞迴演算法出層時需要從棧區退出上層資訊。

首先應用遞迴進層三件事與遞迴退層三件事的原則,直接先給出中序遍歷二 叉樹的非遞迴演算法基本實現思路

演算法思想

(1) 針對左遞迴,寫出遞迴進層的三件事。

(2) 接著寫出左遞迴返回時應執行的語句:訪問根結點。

(3) 接著針對右遞迴,寫出遞迴進層的三件事。

(4) 針對遞迴退層,寫出遞迴退層的三件事(左、右遞迴公用)。

演算法描述】 中序遍歷二叉樹非遞迴演算法初步

void

inorder

(bitree root);

l3:if(top!=0)

}

可看到,直接按定義得到的上述演算法結構並不好,為使程式合理組織,需去掉 goto 語句, 用迴圈句代替 if 與 goto, 此時返回斷點已無保留的必要,棧區只需保留本層引數即可。

整理後的演算法框圖如下圖:

中序遍歷非遞迴演算法需要設定乙個堆疊,用以保留結點指標,以便在遍歷完某個結點的左子樹後,由該結點指標找到該結點的右子樹。

演算法思想

從根結點開始,只要當前結點存在,或者棧不空,則重複下面操作:

(1) 從當前結點開始,進棧並走左子樹,直到左子樹為空。

(2) 退棧並訪問。

(3) 走右子樹。

【演算法描述】 中序遍歷二叉樹的非遞迴演算法 b (直接實現桟操作)

/*s[m] 表示棧,top 表示棧頂指標*/

void

inorder

(bitree root)

/* 中序遍歷二叉樹,root 為二叉樹的根結點 */

/* 遍歷左子樹 */

if(top!=0)

/* 遍歷右子樹 */}}

while

(p!=

null

|| top!=0)

}

void  inorder(bitree root)/* 中序遍歷二叉樹的非遞迴演算法 */

else

}}

遞迴演算法的時間複雜度分析:對有 n 個結點二叉樹,該演算法每迴圈一次,p 指向 乙個結點或空(無左孩子或無右孩子的結點的空鏈域),因此指向空的次數為 n+1,n 為結點個數,故迴圈次數為 n+(n+1)=2n+1,因此演算法的複雜度為 o(n)。

遞迴演算法的空間複雜度分析:所需棧的空間最多等於二叉樹深度 k 乘以每個結 點所需空間數,記作 o(k)。表面上看,遞迴演算法好象並沒有使用棧,實際上遞 歸演算法的執行需要反覆多次的自己呼叫自己。每呼叫一次,系統內部都有系統運 行棧區在支援,這是隱含的棧,需要保留本層引數、臨時變數與返回位址等。隨 著函式遞迴呼叫,執行棧繼續增長,直到函式執行完,才徹底釋放占用的棧空間。 因此遞迴演算法比非遞迴演算法占用的空間更多。

後序遍歷的非遞迴演算法比較複雜。由於後序遍歷是 lrd,要求左、右子樹都 訪問完後,最後訪問根結點。如何判斷當前棧頂結點的左、右子樹都已訪問過?解決的方案有多種,採用的方法是:判斷剛訪問過的結點 q 是不是當前棧頂結點 p 的右孩子。

判別是否應該訪問當前棧頂結點 p 時,有兩種情況:

(1)p 無右孩子,此時應 該訪問根結點;

(2)如 p 的右孩子是剛被訪問過的結點 q(表明 p 的右子樹已遍歷過),此時也應該訪問根結點。除這兩種情況外,均不應訪問根,而是要 繼續進入右子樹中。

因此,演算法採用了記錄剛訪問結點的方法,以便在遍歷過程中利用前驅 q 與當 前結點 p 的關係做判別。

演算法思想

從根結點開始,只要當前結點存在,或者棧不空,則重複下面操作:

(1) 從當前結點開始,進棧並走左子樹,直到左子樹為空;

(2) 如果棧頂結點的右子樹為空,或者棧頂結點的右子孩子為剛訪問過的結 點,則退棧並訪問,然後將當前結點指標置為空;

(3) 否則,走右子樹。

演算法描述】後序遍歷二叉樹的非遞迴演算法(呼叫棧操作的函式)

void

postorder

(bitree root)

/*遍歷左子樹*/if(

!isempty

(s))

else

p=p->rchild;}}

}

二叉樹的遍歷 (遞迴 棧)

二叉樹的遍歷可分為兩種 深度遍歷和廣度遍歷 深度遍歷又分為三種 前序 中序 後序遍歷,這三種遍歷方式可以用遞迴或棧來實現 廣度遍歷 即層序遍歷,可以用佇列來實現 以如下的二叉樹為例,遍歷該二叉樹。a.建立節點類 public class treenode b.根據二叉樹圖建立節點集合 public ...

二叉樹遍歷 遞迴演算法

一 先序 void pre order const btnode b1 先序 二 中序 void in order const btnode b1 中序 三 後序 void post order const btnode b1 後序 四 層次 void level order 直接插到下面 clas...

二叉樹遍歷的遞迴演算法

問題描述 實現二叉樹的先序 中序 後序遍歷的遞迴演算法,並對用 a b d,e h j,k l,m n c f,g i 建立的二叉樹進行測試。請利用二叉樹演算法庫。輸入描述 若干測試資料。程式輸出 二叉樹的輸出。int main void inorder btnode b 中序遍歷的遞迴演算法 vo...