以非递归先根遍历为例。
先把所有的可能的状态列出来,同时把此状态下对应的处理写出来:
表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 }
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 }