今天把二叉樹的非遞歸遍歷算法複習了下,在這總結下。
三個算法都使用了棧,中序和前序遍歷算法大致相同,而後序遍歷稍微複雜一點。
先寫中序遍歷。
//S是 棧,存儲結點,t是樹的根結點
Inorder(t)
//創建棧,將跟結點賦給臨時結點p
Create(S),p = t;
//如果根爲空,返回
IF t = null THEN RETURN
WHILE p!= null AND S!= null
//當存在左子樹的時候,往棧中壓棧
WHILE p!= null THEN
S.push(p);
p = left(p);
//如果棧大小爲空,則返回
IF S = null THEN RETURN
//否則,彈棧,並打印p節點,將p的左子樹壓棧
p = S.pop();
PRINT data(p);
p = left(p);
這樣一個過程就是中序遍歷的過程。
再寫前序,類似於中序,只需將打印的位置改一下即可
//S是 棧,存儲結點,t是樹的根結點
Inorder(t)
//創建棧,將跟結點賦給臨時結點p
Create(S),p = t;
//如果根爲空,返回
IF t = null THEN RETURN
WHILE p!= null AND S!= null
//當存在左子樹的時候,往棧中壓棧,打印p
WHILE p!= null THEN
S.push(p);
PRINT data(p);
p = left(p);
//如果棧大小爲空,則返回
IF S = null THEN RETURN
//否則,彈棧,並打印p節點,將p的左子樹壓棧
p = S.pop();
後序遍歷,稍微複雜點,需要添加一個標記,樹中任意結點都需要進棧三次出棧三次,第一次出棧是爲了遍歷樹的左結點
第二次是爲了遍歷樹的右結點,第三次是爲了訪問該節點。
//如果根結點爲空,返回
IF t = null; THEN RETURN
//創建棧
CREATE(S), S.push(t,0);
//當棧非空時
WHILE S != null
//彈棧
(p,i) = S.pop();
//如果i爲0那麼表明沒遍歷過該結點,將左子樹壓棧
IF i = 0 THEN (S.push(p,1). IF left(p) != null THEN S.push(left(p),0));
//如果i爲1那麼表明左子樹遍歷完成,將右子樹壓棧
IF i = 1 THEN (S.push(p,2). IF righr(p) != null THEN S.push(right(p),0));
//如果i爲3,表明左右遍歷完畢,打印
IF i = 2 THEN PRINT(data(p));