1. 程式人生 > >二叉樹遍歷之遞迴演算法

二叉樹遍歷之遞迴演算法

作者:石鍋拌飯  原文連結


二叉樹的遍歷演算法有多種,典型的有先序遍歷、中序遍歷、後序遍歷以及層序遍歷。而且這些遍歷的遞迴演算法較為簡單,程式碼很少,容易實現,本文就是彙總二叉樹遍歷的遞迴演算法,非遞迴演算法將在下一篇文章中進行總結。本文中用到的二叉樹例項如下:

     3
   /  \
  9   20
     /  \
    15    7

二叉樹定義和輔助函式如下:

[cpp] view plaincopy
  1. struct
     node {  
  2.     int data;  
  3.     struct node* left;  
  4.     struct node* right;  
  5. };  
  6.   
  7. void visit(int data)  
  8. {  
  9.     printf("%d ", data);  
  10. }  

1、先序遍歷

先序遍歷:先訪問二叉樹的根結點,而後遍歷左子樹,最後遍歷右子樹。先序遍歷二叉樹例項結果為:3  9 20 15 7。遞迴演算法程式碼如下:

[cpp] view plaincopy
  1. void preOrder(
    struct node* root)  
  2. {  
  3.     if (root == NULL)  
  4.         return;  
  5.     visit(root->data);  
  6.     preOrder(root->left);  
  7.     preOrder(root->right);  
  8. }  

2、中序遍歷

中序遍歷:先遍歷二叉樹的左子樹,然後訪問根結點,最後遍歷右子樹。中序遍歷二叉樹例項結果:9 3 15 20 7。遞迴演算法程式碼如下:

[cpp] view plaincopy
  1. void inOrder(struct node* root)  
  2. {  
  3.     if (root == NULL)  
  4.         return;  
  5.     inOrder(root->left);  
  6.     visit(root->data);  
  7.     inOrder(root->right);  
  8. }  

3、後序遍歷

後序遍歷:先遍歷二叉樹的左子樹,然後遍歷二叉樹右子樹,最後訪問根結點。後序遍歷二叉樹例項結果:9 15 7 20 3。遞迴演算法程式碼如下:

[cpp] view plaincopy
  1. void postOrder(struct node* root)  
  2. {  
  3.     if (root == NULL)  
  4.         return;  
  5.     postOrder(root->left);  
  6.     postOrder(root->right);  
  7.     visit(root->data);  
  8. }  

4、層序遍歷

對於先序遍歷、中序遍歷以及後序遍歷的遞迴演算法,沒有什麼好說的,時間複雜度都為O(n)。而層序遍歷的遞迴演算法則稍微複雜一點,因為本身層序遍歷用非遞迴演算法是很容易實現的,不過使用遞迴演算法程式碼更簡潔,雖然遞迴演算法的效率並不高。層序遍歷二叉樹例項結果:

3
9 20
15 7
遞迴程式碼如下:

[cpp] view plaincopy
  1. void printLevel(struct node *p, int level)  
  2.  {  
  3.   if (!p) return;  
  4.   if (level == 1) {  
  5.     visit(p->data);  
  6.   } else {  
  7.     printLevel(p->left, level-1);  
  8.     printLevel(p->right, level-1);  
  9.   }  
  10. }  
  11.    
  12. void printLevelOrder(struct node *root)   
  13. {  
  14.   int height = maxHeight(root);  //maxHeight計算二叉樹高度,如二叉樹例項高度為3  
  15.   for (int level = 1; level <= height; level++) {  
  16.     printLevel(root, level);  
  17.     printf("\n");  
  18.   }  
  19. }  

當二叉樹高度為N時,此時遞迴層序遍歷為最壞情況,時間複雜度為O(N^2)。當二叉樹左右子樹基本平衡時,時間複雜度為O(N),分析如下:

設訪問第K層時間為T(k),則T(k)存在如下的遞迴公式:

T(k) = 2T(k-1) + c
     = 2k-1 T(1) + c
     = 2k-1 + c
當二叉樹平衡時,則高度為O(lgN),則總時間為:
T(1) + T(2) + ... + T(lg N)
= 1 + 2 + 22 + ... + 2lg N-1 + c
= O(N)