[存档] 用真值表设计非递归二叉树遍历算法

以非递归先根遍历为例。

先把所有的可能的状态列出来,同时把此状态下对应的处理写出来:

表1 

LeftChild RightChild PreOrder
Exist Visited Exist Visited
Y N Y N //1
cout<<cur<<','; prev = cur; cur = cur->Left; s.push(cur);
Y N N N
Y Y Y N //2
prev = cur; cur = cur->Right; s.push(cur);
Y Y N N //3
s.pop(); prev = cur; cur = s.top();
Y Y Y Y //3
s.pop(); prev = cur; cur = s.top();
N N Y N //4
cout<<cur<<','; prev = cur; cur = cur->Right; s.push(cur);
N N Y Y //3
s.pop(); prev = cur; cur = s.top();
N N N N //5
cout<<cur<<','; prev = cur; s.pop(); cur = s.top();

接下来,我们可以用前一个处理过的节点和当前节点的关系来判断当前状态,同时需要结合子树的结构做出不同的处理。

当前节点的子树有4种可能的结构:只有左子树,只有右子树,左右子树都有,没有子树。

两个判断条件的不同组合,可以对应到表1的状态,然后把相应的处理语句填入。

表2

Only LeftChild LeftChile&RightChild Only Right Child none
pre = left 3 2 N/A N/A
pre = right N/A 3 3 N/A
pre <> left && pre <> right 1 1 4 5

最后,根据表2设计程序。可以看到某些判断条件的组合其实对应的是同样的处理语句,于是合并处理之。

得到如下程序:

 1 void N_PreOrder(TreeNode *root){
 2     
 3     if(!root){
 4         cout<<"Empty tree"<<'\n';
 5         return;
 6     }
 7     stack<TreeNode *> s;
 8     TreeNode *cur = root;
 9     TreeNode *prev = root;
10     s.push(root);
11     while(!s.empty()){
12         if(prev == cur->Right){
13             s.pop(); prev = cur; 
14             if(!s.empty()){
15                 cur = s.top(); 
16             }
17         }else if(prev == cur->Left){ 
18             if(cur->Right){
19                 prev = cur; cur = cur->Right;s.push(cur);
20             }else{
21                 s.pop(); prev = cur; 
22                 if(!s.empty()){
23                     cur = s.top(); 
24                 }
25             }
26         }else {
27             cout<<cur->Value<<','; prev = cur; 
28             if(cur->Left){
29                 cur = cur->Left; s.push(cur);
30             }else if(cur->Right){
31                 cur = cur->Right; s.push(cur);
32             }else{
33                 s.pop(); 
34                 if(!s.empty()){
35                     cur = s.top(); 
36                 }
37             }
38         }
39     }
40     cout<<"end"<<'\n';    
41 }
原文地址:https://www.cnblogs.com/k330/p/Cpp_NonRecursive_BinTree_PreOrderTraversal.html