資料結構 樹的前序 中序 後續遍歷的非遞迴寫法

2022-05-20 20:03:27 字數 1039 閱讀 5332

理解的精髓在於用"棧"來取代遞迴,出棧的操作其實就相當於某層遞迴的出口

【前序遍歷】

用棧來替代遞迴的過程(因為遞迴歸根到底也是用棧來實現的)

考慮遞迴的時候 每進入乙個遞迴都會往左子樹試探,因此一直往左子樹走到頭,遇到乙個節點就訪問它

然後壓入棧中 訪問完左子樹之後再回過頭繼續對每個節點的右子樹進行"遞迴操作"

1

void

preorder()

9if (!s.empty())14}

15 }

【中序遍歷】

和中序遍歷結構一樣,只是訪問的時刻變了,只有左子樹訪問完了才開始訪問棧中的節點(迎合中序遍歷的要求)

1

void

middleorder()

8if (!s.empty())14}

15 }

【後序遍歷】

基本的思路和中序遍歷、前序遍歷類似。

但是需要考慮乙個問題,就是當到達s.top()這個點的時候,雖然s.top()的左子樹都已經訪問完了。

但是不能保證s.top()的右子樹訪問完了。所以只有當s.top()的右子樹為空,或者s.top()的右子樹的根節點

已經訪問過了(或者可以說前乙個訪問的點是s.top()的右子樹的根節點,因為訪問完右子樹的根節點肯定就接著訪問的是s.top()了),

那麼就可以直接訪問s.top()了,否則這個點還不到該訪問的時候,因此還得入棧,遞迴他的右子樹。

可以回憶一下遞迴的寫法,會發現某個點x要在遞迴dfs(l[x])和dfs(r[x])之後才能訪問(後續遍歷),因此可以想見這個點s.top()需要入棧兩次

之後才能保證要開始訪問s.top()了,所以另一種寫法是,記錄這個點是第幾次入棧了,如果是第二次,那麼就可以等下次彈出的時候直接輸出了。

**中給的是,記錄上次訪問的是哪個節點,也是可以的,比較方便)

1

void

laterorder()

9if (!s.empty())else18}

19}20 }

資料結構 樹 樹的前序 中序 後序遍歷詳解

zlingyun 遍歷是針對根節點的 前序遍歷順序 根節點 左子樹 右子樹,根左右 中序遍歷順序 左子樹 根節點 右子樹,左根右 後序遍歷順序 左子樹 右子樹 根節點,左右根 深入一點去理解這個排序順序是這樣的 前序遍歷首先訪問根結點,然後遍歷左子樹,最後遍歷右子樹。在遍歷左 右子樹時,仍然先訪問根...

資料結構 樹的遍歷(前序)

前序遍歷 dlr 前序遍歷也叫做先根遍歷 先序遍歷,可記做根左右。前序遍歷首先訪問根結點然後遍歷左子樹,最後遍歷右子樹。在遍歷左 右子樹時,仍然先訪問根結點,然後遍歷左子樹,最後遍歷右子樹。二叉樹游標前序遍歷類 public class mybitreepreiterator extends myb...

資料結構 前序,中序 後續序歷演算法(c語言)

include include include 二叉鏈表示法 typedef struct bitnode bitnode,bitree 呼叫preorder t1 t1是根結點,不為null,執行printf d t root data 列印出來1 呼叫preorder root lchild 訪...