二叉樹的遍歷方式有四種:遍歷的時候記住,左子樹一定是先於右子樹遍歷的,根最先遍歷就是先序遍歷,根在中間就是中序遍歷,根在最後遍歷就是後序遍歷。並且,遍歷左子樹和右子樹的時候,遍歷的方式也是遵循大的遍歷規則,比如二叉樹遍歷方式爲先序遍歷,那麼左子樹和右子樹遍歷的時候,也是按照這種方式進行遍歷。
- DLR – 先序遍歷:(先根遍歷)先根 再左 再右
- LDR – 中序遍歷:(中根遍歷)先左 再根 再右
- LRD – 後序遍歷:(後跟遍歷)先左 再右 再根
- 層次遍歷 – :一層一層往下遍歷(這個用的比較少)
對於上面這棵二叉樹,它的遍歷結果爲:
先序遍歷:ABDECFG
中序遍歷:DBEAFCG
後續遍歷:DEBFGCA
層次遍歷:ABCDEFG
二叉樹自身具有遞歸特性,所以可以利用遞歸對二叉樹進行遍歷。
先定義一個結構體:
//二叉樹節點結構體
typedef struct BinaryTreeNode
{
char data; //數據 假設爲char類型
BinaryTreeNode *left; //左孩子節點
BinaryTreeNode *right; //右孩子節點
}Node;
一、先序遍歷
//先序遍歷
void preOrder(const Node*root)
{
if (NULL == root)
{
return;
}
printf("%c ", root->data);
preOrder(root->left);
preOrder(root->right);
}
二、中序遍歷
//中序遍歷
void inOrder(const Node*root)
{
if (NULL == root)
{
return;
}
inOrder(root->left);
printf("%c ", root->data);
inOrder(root->right);
}
三、後序遍歷
//後序遍歷
void laOrder(const Node *root)
{
if (NULL == root)
{
return;
}
laOrder(root->left);
laOrder(root->right);
printf("%c ", root->data);
}
綜合三種遍歷方式,發現在遞歸的方式中
laOrder(root->left);
laOrder(root->right);
printf("%c ", root->data); //這條語句在第一行就是先序遍歷,中間就是中序遍歷,最後就是後序遍歷
四、層次遍歷
因爲層次遍歷是從上到下,從左到右 逐行遍歷的,這種類型爲廣度遍歷。而前三個遍歷方式,爲深度遍歷。所以對於層次遍歷不建議用遞歸的方式。但是爲了統一,我這裏也寫一個遞歸的層次遍歷。
//層次遍歷
void leOrder(const Node *root,const int depth,int once = 0)
{
if (NULL == root || 0 == depth)
{
return;
}
if(once)
printf("%c ", root->data);
if (NULL != root->left)
printf("%c ", root->left->data);
if (NULL != root->right)
printf("%c ", root->right->data);
leOrder(root->left, depth - 1);
leOrder(root->right, depth - 1);
}
這個遞歸看上去也挺像的。
看一下自己的main函數,測試的代碼:
int main()
{
//準備數據
Node nodeA = { 'A',NULL,NULL };
Node nodeB = { 'B',NULL,NULL };
Node nodeC = { 'C',NULL,NULL };
Node nodeD = { 'D',NULL,NULL };
Node nodeE = { 'E',NULL,NULL };
Node nodeF = { 'F',NULL,NULL };
Node nodeG = { 'G',NULL,NULL };
//建立關係
nodeA.left = &nodeB;
nodeA.right = &nodeC;
nodeB.left = &nodeD;
nodeB.right = &nodeE;
nodeC.left = &nodeF;
nodeC.right = &nodeG;
//調用遞歸函數
preOrder(&nodeA);
printf("\n");
inOrder(&nodeA);
printf("\n");
laOrder(&nodeA);
printf("\n");
leOrder(&nodeA,3,1);
printf("\n");
system("pause");
return 0;
}
運行的結果也看一下:
遞歸挺佔用資源的,所以可以用棧的方式實現前、中、後序遍歷,用隊列或者數組什麼的實現層次遍歷。這個實現後面在寫了。