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


    以非递归先根遍历为例。

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

    表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 }
  • 相关阅读:
    pycharm下载与安装
    IOS 字体表
    iOS 在 ARC 环境下 dealloc 的使用、理解误区
    微信支付的开发
    Undefined symbols for architecture i386:和"_OBJC_CLASS_$_xx", referenced from:问题解决方法
    soureTree使用
    UINavigationController 直接pop到指定controllerView的方法
    OBC: NSString 与 NSArray 互转
    NSArray的containsObject的使用时注意的问题
    IOS 自定义导航栏标题和返回按钮标题
  • 原文地址:https://www.cnblogs.com/k330/p/Cpp_NonRecursive_BinTree_PreOrderTraversal.html
Copyright © 2020-2023  润新知