zoukankan      html  css  js  c++  java
  • Binary Tree Traversal Algorithms (二叉树遍历算法)

    本文共列出了11个常见的二叉树遍历算法。二叉树的遍历主要有深度优先遍历和广度优先遍历。深度优先遍历包含前序遍历、中序遍历和后序遍历。

    值得一提的是, 其中的 Morris 算法 可以线性时间不需要额外空间(用户栈或系统栈空间)实现二叉树的前序遍历、中序遍历和后序遍历。关于Morris算法, 可参考 http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html

    算法清单:

      A1、 A2、 A3, 分别是中序遍历的递归、迭代、和Morris算法实现。  

      A4、 A5、 A6, 分别是前序遍历的递归、迭代、和Morris算法实现。

      A7、 A8、 A9, 分别是后序遍历的递归、迭代、和Morris算法实现。

      A10 是广度优先遍历算法实现。

      A11 ZigZag顺序的遍历算法。

    C++源代码:

      1 #include <iostream>
      2 #include <stack>
      3 #include <queue>
      4 using namespace std;
      5 
      6 struct bt_node {
      7     int value;
      8     bt_node *left, *right;
      9     bt_node(int val = 0) 
     10         : value(val), left(NULL), right(NULL) {} 
     11 };
     12 
     13 void process(bt_node* pnode) {
     14     if (pnode != NULL) 
     15         cout << pnode->value << " ";
     16 }
     17 
     18 // A1
     19 void recursive_inorder_traversal(bt_node* root) {
     20     if (root != NULL) {
     21         recursive_inorder_traversal(root->left);
     22         process(root);
     23         recursive_inorder_traversal(root->right);
     24     }
     25 }
     26 
     27 // A2
     28 void iterative_inorder_traversal(bt_node* root) {
     29     stack<bt_node*> _stack;
     30     bt_node* p = root;
     31     while (p != NULL) {
     32         while (p != NULL) {
     33             _stack.push(p);
     34             p = p->left;
     35         }
     36         p = _stack.top();
     37         _stack.pop();
     38         process(p);
     39         while (p->right == NULL && !_stack.empty()) {
     40             p = _stack.top();
     41             _stack.pop();
     42             process(p);
     43         }
     44         p = p->right;
     45     }
     46 }
     47 
     48 // A3 
     49 void morris_inorder_traversal(bt_node* root) {
     50     bt_node* p = root;
     51     while (p != NULL) {
     52         if (p->left == NULL) {
     53             process(p);
     54             p = p->right;
     55         } else {
     56             bt_node* tmp = p->left;
     57             while (tmp->right != NULL && tmp->right != p) {
     58                 tmp = tmp->right;
     59             }
     60             if (tmp->right == NULL) {
     61                 tmp->right = p;
     62                 p = p->left;
     63             } else {
     64                 tmp->right = NULL;
     65                 process(p);
     66                 p = p->right;
     67             }
     68         }
     69     }
     70 }
     71 
     72 // A4
     73 void recursive_preorder_traversal(bt_node* root) {
     74     if (root != NULL) {
     75         process(root);
     76         recursive_preorder_traversal(root->left);
     77         recursive_preorder_traversal(root->right);
     78     }
     79 }
     80 
     81 // A5
     82 void iterative_preorder_traversal(bt_node* root) {
     83     stack<bt_node*> _stack;
     84     bt_node* p = root;
     85     while (p != NULL) {
     86         while (p != NULL) {
     87             process(p);
     88             _stack.push(p);
     89             p = p->left;
     90         }
     91         p = _stack.top();
     92         _stack.pop();
     93         while (p->right == NULL && !_stack.empty()) {
     94             p = _stack.top();
     95             _stack.pop();
     96         }
     97         p = p->right;
     98     }
     99 }
    100 
    101 // A6
    102 void morris_preorder_traversal(bt_node* root) {
    103     bt_node* p = root;
    104     while (p != NULL) {
    105         if (p->left == NULL) {
    106             process(p);
    107             p = p->right;
    108         } else {
    109             bt_node* tmp = p->left;
    110             while (tmp->right != NULL && tmp->right != p) 
    111                 tmp = tmp->right;
    112             if (tmp->right == NULL) {
    113                 tmp->right = p;
    114                 process(p);
    115                 p = p->left;
    116             } else {
    117                 tmp->right = NULL;
    118                 p = p->right;
    119             }
    120         }
    121     }
    122 }
    123 
    124 
    125 // A7
    126 void recursive_postorder_traversal(bt_node* root) {
    127     if (root != NULL) {
    128         recursive_postorder_traversal(root->left);
    129         recursive_postorder_traversal(root->right);
    130         process(root);
    131     }
    132 }
    133 
    134 // A8
    135 void iterative_postorder_traversal(bt_node* root) {
    136     stack<bt_node*> _stack;
    137     bt_node *p = root, *q = NULL;
    138     while (p != NULL) {
    139         _stack.push(p);
    140         p = p->left;
    141     }
    142     while (!_stack.empty()) {
    143         p = _stack.top();
    144         if (p->right == NULL || p->right == q) {
    145             _stack.pop();
    146             process(p);
    147             q = p;
    148         } else {
    149             p = p->right;
    150             while (p != NULL) {
    151                 _stack.push(p);
    152                 p = p->left;
    153             }
    154         }
    155     }
    156 }
    157 
    158 bt_node* reverse(bt_node* pnode) {
    159     bt_node aux_node;
    160     bt_node* p = &aux_node;
    161     bt_node* q = pnode;
    162     while (q != NULL) {
    163         bt_node* next = q->right;
    164         q->right = p->right;
    165         p->right = q;
    166         q = next;
    167     }
    168     return p->right;
    169 }
    170 
    171 void process_in_reverse_order(bt_node* pnode) {
    172     pnode = reverse(pnode);
    173     bt_node* p = pnode;
    174     while (p != NULL) {
    175         process(p);
    176         p = p->right;
    177     }
    178     reverse(pnode);
    179 }
    180 
    181 // A9
    182 void morris_postorder_traversal(bt_node* root) {
    183     bt_node dummy;
    184     dummy.left = root;
    185     bt_node *p = &dummy;
    186     while (p != NULL) {
    187         if (p->left == NULL) {
    188             p = p->right;
    189         } else {
    190             bt_node* tmp = p->left;
    191             while (tmp->right != NULL && tmp->right != p) 
    192                 tmp = tmp->right;
    193             if (tmp->right == NULL) {
    194                 tmp->right = p;
    195                 p = p->left;
    196             } else {
    197                 tmp->right = NULL;
    198                 process_in_reverse_order(p->left);
    199                 p = p->right;
    200             }
    201         }
    202     }
    203 }
    204 
    205 // A10
    206 void breadth_first_traversal(bt_node* root) {
    207     queue<bt_node*> _queue;
    208     _queue.push(root);
    209     while (!_queue.empty()) {
    210         bt_node* p = _queue.front();
    211         _queue.pop();
    212         process(p);
    213         if (p->left != NULL) {
    214             _queue.push(p->left);
    215         } 
    216         if (p->right != NULL) {
    217             _queue.push(p->right);
    218         }
    219     }
    220 }
    221 
    222 // A11
    223 void zigzag_order_traversal(bt_node* root) {
    224     stack<bt_node*> _stack1;
    225     stack<bt_node*> _stack2;
    226     _stack1.push(root);
    227     int left_first = 1;
    228     while (!_stack1.empty()) {
    229         while (!_stack1.empty()) {
    230             bt_node* p = _stack1.top();
    231             _stack1.pop();
    232             process(p);
    233             if (left_first) {
    234                 if (p->left != NULL)
    235                     _stack2.push(p->left);
    236                 if (p->right != NULL) 
    237                     _stack2.push(p->right);
    238             } else {
    239                 if (p->right != NULL)
    240                     _stack2.push(p->right);
    241                 if (p->left != NULL)
    242                     _stack2.push(p->left);
    243             }
    244         }
    245         left_first = left_first ^ 0x01;
    246         _stack1.swap(_stack2); // C++11 Standard
    247     }
    248 }
    249 
    250 // Test
    251 int main() {
    252     const int n = 7;
    253     bt_node* ptr[n];
    254     for (int i = 0; i < n; i++) {
    255         ptr[i] = new bt_node(i+1);
    256     }
    257     ptr[0]->left = ptr[1];
    258     ptr[0]->right = ptr[2];
    259     ptr[1]->left = ptr[3];
    260     ptr[1]->right = ptr[4];
    261     ptr[2]->left = ptr[5];
    262     ptr[4]->left = ptr[6];
    263 
    264     /*
    265      *             1
    266      *           /   
    267      *          2     3
    268      *         /    /
    269      *        4   5 6 
    270      *           /
    271      *          7
    272      */
    273 
    274     recursive_inorder_traversal(ptr[0]);
    275     cout << endl;
    276     iterative_inorder_traversal(ptr[0]);
    277     cout << endl;
    278     morris_inorder_traversal(ptr[0]);
    279     cout << endl;
    280 
    281     recursive_preorder_traversal(ptr[0]);
    282     cout << endl;
    283     iterative_preorder_traversal(ptr[0]);
    284     cout << endl;
    285     morris_preorder_traversal(ptr[0]);
    286     cout << endl;
    287 
    288     recursive_postorder_traversal(ptr[0]);
    289     cout << endl;
    290     iterative_postorder_traversal(ptr[0]);
    291     cout << endl;
    292     morris_postorder_traversal(ptr[0]);
    293     cout << endl;
    294 
    295     breadth_first_traversal(ptr[0]);
    296     cout << endl;
    297     zigzag_order_traversal(ptr[0]);
    298     cout << endl;
    299 
    300     for (int i = 0; i < n; i++) {
    301         delete ptr[i];
    302     }
    303     return 0;
    304 }

    程序输出:

    4 2 7 5 1 6 3 
    4 2 7 5 1 6 3 
    4 2 7 5 1 6 3 
    1 2 4 5 7 3 6 
    1 2 4 5 7 3 6 
    1 2 4 5 7 3 6 
    4 7 5 2 6 3 1 
    4 7 5 2 6 3 1 
    4 7 5 2 6 3 1 
    1 2 3 4 5 6 7 
    1 3 2 4 5 6 7
  • 相关阅读:
    一个很好的Delphi博客
    Android开发之adb无法连接
    J2EE--常见面试题总结 -- (二)
    J2EE--常见面试题总结 -- ( 一)
    面向接口编程实现不改代码实现Redis单机/集群之间的切换
    Gradle sync failed 异常
    Dubbo+Zookeeper
    JdbcTemplate的使用
    Spring -- 配置bean
    浅析 @PathVariable 和 @RequestParam(转发,非原创)
  • 原文地址:https://www.cnblogs.com/william-cheung/p/4623792.html
Copyright © 2011-2022 走看看