二叉树的非递归操作

这里涉及到二叉树的非递归操作有:先序遍历、中序遍历、后序遍历

====数据结构====

树结点:
struct Node
{
    
char data;
    Node 
* left;
    Node 
* right;
};

标志:
enum Tag{goLeft, goRight, goBack };
goLeft指示访问左子树
goLeft指示访问右子树(左子树已访问)
goBack指示回溯(左右子树均已访问)

两个栈:
vector<Node *> vec_node;
vector
<Tag> vec_flag;
两个栈同时消长、空

所有操作相同的部分:
Node *curNode = vec_node.back();//栈顶
Tag curFlag = vec_flag.back();  //栈顶

switch(curFlag)
        {
            
case goLeft:
                
//更改标志
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
//左子树入栈
                if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                
//更改标志
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
//右子树入栈
                if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goBack:
                
//结点出栈
                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end

几种操作唯一不同的是:需要的操作放置的位置不同。
先序遍历:打印结点放在goLeft中
中序遍历:打印结点放在goRight中
后续遍历:打印结点放在goBack中
打印所有路径:在goBack中判断是否为叶子结点,如果是,打印栈中所有路径;如果否,直接出栈

详细代码见下面:(注意其中红色的地方是唯一差别的地方:
#include <iostream>
#include 
<vector>
#include 
<cstdlib>
using namespace std;


struct Node
{
    
char data;
    Node 
* left;
    Node 
* right;
};

enum Tag{goLeft, goRight, goBack };

void PreOrder(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while(!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();

        
switch(curFlag)
        {
            
case goLeft:
                cout << curNode->data << "  ";
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:
                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end

}

void InOrder(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while(!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();

        
switch(curFlag)
        {
            
case goLeft:
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                cout << curNode->data << "  ";
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:


                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end

}

void PostOrder(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while(!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();

        
switch(curFlag)
        {
            
case goLeft:
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:
                cout << curNode->data << "  ";


                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end

}


/* 打印从根到叶子结点之路径 */
void PrintPath( const vector<Node *> & v )
{
    vector
< Node *>::const_iterator vi;
    
for( vi = v.begin(); vi!=v.end(); ++vi )
    {
        Node 
* n = reinterpret_cast< Node *>(*vi);
        cout
<< n->data<< " ";
    }
    cout
<< endl;
}

void PrintAllPaths(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();


        
switch(curFlag)
        {
            
case goLeft:
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:
                
if(NULL == curNode->left && NULL == curNode->right)
                    PrintPath(vec_node);

                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end
}

int main()
{
    Node root, b, c, d, e, f, g, h;
    root.data
='a';
    root.left
=&b;
    root.right
=&e;

    b.data
='b';
    b.left
=&c;
    b.right
=&d;

    c.data
='c';
    c.left
=NULL;
    c.right
=NULL;

    d.data
='d';
    d.left
=NULL;
    d.right
=NULL;

    e.data
='e';
    e.left
=&f;
    e.right
=&g;

    f.data
='f';
    f.left
=NULL;
    f.right
=NULL;

    g.data
='g';
    g.left
=NULL;
    g.right
=&h;

    h.data
='h';
    h.left
=NULL;
    h.right
=NULL;


    cout 
<< "Print all paths:\n";
    PrintAllPaths(
&root);
    cout 
<< "\n";

    cout 
<< "PostOrder:\n";
    PostOrder(
&root);
    cout 
<< "\n";

    cout 
<< "PreOrder:\n";
    PreOrder(
&root);
    cout 
<< "\n";

    cout 
<< "InOrder:\n";
    InOrder(
&root);
    cout 
<< "\n\n";

    system(
"PAUSE");
    
return 0;
}

运行结果:
posted @ 2007-10-24 11:08  中土  阅读(784)  评论(0编辑  收藏  举报
©2005-2008 Suprasoft Inc., All right reserved.