主要過程就是遞迴呼叫,也可以用棧來實現。
對於先序遍歷來說,藍色剪頭第一次經過的結點,就是遍歷的序列,以後再次經歷就不算進去了。
typedef struct非遞迴的先序遍歷binode binode, *bitree;
void preorder(binode *root)
//end of if
}
根據前序遍歷訪問的順序,優先訪問根結點,然後再分別訪問左孩子和右孩子。即對於任一結點,其可看做是根結點,因此可以直接訪問,訪問完之後,若其左孩子不為空,按相同規則訪問它的左子樹;當訪問其左子樹時,再訪問它的右子樹。因此其處理過程如下:
對於任一結點p:
1)訪問結點p,並將結點p入棧;
2)判斷結點p的左孩子是否為空,若為空,則取棧頂結點並進行出棧操作,並將棧頂結點的右孩子置為當前的結點p,迴圈至1);若不為空,則將p的左孩子置為當前的結點p;
3)直到p為null並且棧為空,則遍歷結束。
//中序遍歷、後序遍歷和先序遍歷思想基本類似,對於中序遍歷來說,藍色剪頭第二次經過的結點,就是遍歷的序列,之前的和以後的再次經歷就不算進序列裡去了。對於後序遍歷來說,藍色剪頭第三次經過的結點,就是遍歷的序列,之前經歷的就不算進去了。關鍵在於何時訪問的語句的位置
void
preorder(bitree root)
//p == null
if (!nodes.empty()) }}
ldr左跟右:中序遍歷左子樹、訪問根結點、中序遍歷右子樹
若二叉樹非空
(1)中序遍歷左子樹;
(2)訪問根結點;
(3)中序遍歷右子樹;
若二叉樹為空,結束——基本項(也叫終止項)
若二叉樹非空——遞迴項
(1)中序遍歷左子樹;
(2)訪問根結點;
(3)中序遍歷右子樹;
中序遞迴遍歷演算法
void inorder(binode *root)中序的非遞迴遍歷,使用棧//end of if
}
非遞迴的中序遍歷二叉樹
void
inorder(bitree root)
//需要判斷空否,因為需要出棧操作
if (!nodes.empty())
}//end of while
}lrd左右跟:後序遍歷左子樹、後序遍歷右子樹、訪問根結點
後序遍歷序列:bdfgeca
//同理有非遞迴的後續遍歷二叉樹遞迴後續遍歷二叉樹
void
lastorder(bitree root)
}
在後序遍歷中,要保證左孩子和右孩子都已被訪問,並且左孩子在右孩子訪問之後才能訪問根結點。因此對於任一結點p,先將其入棧。如果p不存在左孩子和右孩子,則可以直接訪問它;或者p存在左孩子或者右孩子,但是其左孩子和右孩子都已被訪問過了,則同樣可以直接訪問該結點。若非上述兩種情況,則將p的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。
void postorder3(bitree root) //二叉樹遍歷的總結:非遞迴後序遍歷
else
//如果當前結點的左子樹不為空
if(cur->lchild !=null)}}
}
無論先序、中序、後序遍歷二叉樹,遍歷時的搜尋路線是相同的:從根節點出發,逆時針延二叉樹外緣移動,對每個節點均途經三次。
先序遍歷:第一次經過節點時訪問。(abcd)
中序遍歷:第二次經過節點時訪問。(badc)
後序遍歷:第三次經過節點時訪問。(bdca)
二叉樹的遍歷方式(遞迴 非遞迴)
二叉樹的前序 中序 後序遍歷方式,遞迴與非遞迴。層序遍歷的方式已經在之前的部落格中寫過 遞迴方式比較簡單。前序遍歷 void preorder treenode root 前序遍歷非遞迴 基本思路 利用棧。先輸出結點值,再入棧。然後遍歷左子樹。退棧時,遍歷棧頂結點的右子樹。void preorder...
二叉樹的遍歷 非遞迴方式
分別用非遞迴的方式實現二叉樹的先序遍歷 中序遍歷和後續遍歷 非遞迴方式實現二叉樹的先序遍歷。過程 1.申請乙個新的棧,記為stack,然後將二叉樹的頭結點head壓入stack中。2.從stack中彈出棧頂結點,記為cur,然後列印cur結點的值,再將結點cur的右孩子 不為空的話 先壓入stack...
二叉樹 遞迴 非遞迴
include include include include using namespace std typedef struct node bintree typedef struct node1 btnode void creatbintree char s,bintree root 建立二叉...