在講遍歷之前,我們要先建立一個樹:
#include <iostream> using namespace std; typedef struct node; typedef node *tree; struct node{ int data; // 結點數值 tree left,right; // 左子樹和右子樹 }; tree bt;
遍歷二叉樹有三種方式:
先序遍歷
先序遍歷的操作如下:
- 訪問根結點
- 先序遍歷左子樹(遞迴)
- 先序遍歷右子樹(遞迴)
二叉樹bt的先序遍歷結果:12347536
程式碼如下:
void preorder(tree bt){ if (bt){ // 判斷不為空二叉樹 cout << bt.data; preorder(bt.left); // 遞迴遍歷左子樹 preorder(bt.right); // 遞迴遍歷右子樹 } }
中序遍歷
中序遍歷的操作如下:
- 中序遍歷左子樹(遞迴)
- 訪問根結點
- 中序遍歷右子樹(遞迴)
二叉樹bt的中序遍歷結果:7425136
程式碼如下:
void inorder(tree bt){ if (bt){ // 判斷不為空二叉樹 inorder(bt.left); // 遞迴遍歷左子樹 cout << bt.data; inorder(bt.right); // 遞迴遍歷右子樹 } }
後序遍歷
後序遍歷的操作如下:
- 後序遍歷左子樹(遞迴)
- 後序遍歷右子樹(遞迴)
- 訪問根結點
二叉樹bt的後序遍歷的結果:7452631
程式碼如下:
void postorder(tree bt){ if (bt){ // 判斷不為空二叉樹 postorder(bt.left); // 遞迴遍歷左子樹 postorder(bt.right); // 遞迴遍歷右子樹 cout << bt.data; } }
小結:我們使用遞迴的方式遍歷了二叉樹,大家仔細觀察可以發現,先序遍歷就是先訪問根結點,再遞迴,中序遍歷是把訪問根結點放中間,後續遍歷是最後訪問。
總程式碼:
#include <iostream> using namespace std; typedef struct node; typedef node *tree; struct node{ int data; // 結點數值 tree left,right; // 左子樹和右子樹 }; tree bt; void preorder(tree bt){ if (bt){ // 判斷不為空二叉樹 cout << bt.data; preorder(bt.left); // 遞迴遍歷左子樹 preorder(bt.right); // 遞迴遍歷右子樹 } } void inorder(tree bt){ if (bt){ // 判斷不為空二叉樹 inorder(bt.left); // 遞迴遍歷左子樹 cout << bt.data; inorder(bt.right); // 遞迴遍歷右子樹 } } void postorder(tree bt){ if (bt){ // 判斷不為空二叉樹 postorder(bt.left); // 遞迴遍歷左子樹 postorder(bt.right); // 遞迴遍歷右子樹 cout << bt.data; } }
補充知識:
表示式:a+b*c
表示式二叉樹:
字首表示式(波蘭式):+a*bc
中綴表示式:a+b*c/d
字尾表示式(逆波蘭式):abc*+
怎麼將中綴表示式轉換為字首表示式或字尾表示式呢?只需像前序遍歷和後序遍歷一樣遍歷表達二叉樹即可。