二叉树的建立、销毁、各种遍历(递归、非递归)

二叉树的基本操作,都使用递归:

//二叉树   
class Node  
{  
public:  
    char data;  
    Node *left;  
    Node *right;  
    Node():data(' '),left(NULL),right(NULL){}  
    Node(char ch):data(ch),left(NULL),right(NULL){}  
};  
  
  
//广义表建立二叉树,输入:A(B(D,E(G,)),C(,F))*   
void CreateBinTree(Node* & Root,char *str)  
{  
    stack<Node*> s;  
    Root=NULL;  
    Node* p=NULL,*t=NULL;  
    int k,i=0;  
    while(str[i])  
    {  
        switch(str[i])  
        {  
            case '(': s.push(p); k=1; break;  
            case ')': t=s.top(); s.pop(); break;  
            case ',': k=2; break;  
            default:  
            p=new Node(str[i]);  
            if(Root==NULL) Root=p;  
            else if(k==1)  
            {  
                t=s.top(); t->left=p;  
            }  
            else  
            {  
                t=s.top(); t->right=p;  
            }  
        }  
        ++i;  
    }  
}  
  
//递归先序遍历   
void preOrderTraverse(Node *p)  
{  
   if(p != NULL)  
   {  
       cout<<p->data;  
       preOrderTraverse(p->left);  
       preOrderTraverse(p->right);  
   }  
}  
  
//求节点个数   
int Size(Node* root)  
{  
    if(root == NULL) return 0;  
    return 1 + Size(root->left) + Size(root->right);  
}  
  
//求树的高度   
int TreeDepth(Node* t)  
{  
    int hl,hr,h;  
    if(t != NULL)  
    {  
        hl = TreeDepth(t->left);  
        hr = TreeDepth(t->right);  
        h = hl>hr? hl:hr;  
        return h+1;  
    }  
    return 0;  
}  
  
//销毁二叉树   
void freeTree(Node*& p)  
{  
    if(p->left != NULL)  
        freeTree(p->left);  
    if(p->right != NULL)  
        freeTree(p->right);  
    delete(p);  
}  

二叉树的各种遍历:

//输出第level层的所有节点(从左到右),成功返回1   
int PrintNodeAtLevel(Node* root,int level)  
{  
    if(!root || level<0)  return 0;  
    if(level==0)  
    {  
        cout<<root->data<<" ";  
        return 1;  
    }  
    return PrintNodeAtLevel(root->left,level-1)+PrintNodeAtLevel(root->right,level-1);  
}  
  
//层次遍历二叉树,使用树的高度   
void PrintNodeByLevel(Node* root,int depth)  
{  
    for(int level=0; level<depth; level++)  
    {  
        PrintNodeAtLevel(root,level);  
        cout<<endl;  
    }  
}  
//层次遍历二叉树,不使用树的高度   
void PrintNodeByLevel(Node* root)  
{  
    for(int level=0; ;level++)  
    {  
        if(!PrintNodeAtLevel(root,level)) break;  
        cout<<endl;  
    }  
}  
  
/*层次遍历树算法: 
        (1)初始化队列为空 
        (2)若二叉树为空,直接返回 
        (3)将根节点指针放到队列中 
        (4)若队列非空,则重复以下操作: 
          1.队头元素出队并访问该元素 
          2.若该节点左孩子非空,则左孩子节点指针入队 
          3.若该节点右孩子非空,则右孩子节点指针入队 
*/  
void layerOrder(Node* t)//层次遍历树   
{  
    queue<Node*> q;  
    if(t==NULL) return;  
    q.push(t);  
    while(!q.empty())  
    {  
        Node* p=q.front();  
        q.pop();  
        cout<<p->data<<" ";  
        if(p->left) q.push(p->left);  
        if(p->right) q.push(p->right);  
    }  
}  
  
//层次遍历二叉树   
void LevelOrder(Node* root)  
{  
    if(root==NULL) return;  
    vector<Node*> v;  
    v.push_back(root);  
    int cur=0;  
    int last=1;  
    while(cur<v.size())  
    {  
        last=v.size();  
        while(cur<last)  
        {  
            cout<<v[cur]->data<<" ";  
            if(v[cur]->left) v.push_back(v[cur]->left);  
            if(v[cur]->right) v.push_back(v[cur]->right);  
            cur++;  
        }  
        cout<<endl;  
    }  
}  
  
//非递归先序遍历树   
void preOrder(Node* root)  
{  
    stack<Node*> s;  
    Node* p=NULL;  
    if(root==NULL) return;  
    s.push(root);  
    while(!s.empty())  
    {  
        p=s.top(); s.pop();  
        cout<<p->data<<" ";  
        if(p->right) s.push(p->right);  
        if(p->left) s.push(p->left);  
    }  
}  
  
//非递归先序遍历树   
void preOrder(Node* t)  
{  
    stack<Node*> s;  
    Node* p=t;  
    while (p!=NULL || !s.empty())  
    {  
        while (p!=NULL)  //遍历左子树   
         {  
            cout<<p->data<<" ";  
            s.push(p);  
            p=p->left;  
        }  
        if (!s.empty()) //通过下一次循环中的内嵌while实现右子树遍历   
         {  
            p=s.top();  
            s.pop();  
            p=p->right;  
        }  
     }  
}  
  
/*非递归中序遍历树算法:从根节点开始,只要当前节点存在,或者栈不为空,则重复下面操作: 
  (1)如果当前节点存在,则进栈并走左子树。 
  (2)否则退栈并访问,然后走右子树。 
*/  
void inOrder(Node* t)  
{  
    stack<Node*> s;  
    Node* p=t;  
    while(p||!s.empty())  
    {  
        if(p)  
        {  
            s.push(p);  
            p=p->left;  
        }  
        else  
        {  
            p=s.top();s.pop();  
            cout<<p->data<<" ";  
            p=p->right;  
        }  
    }  
}  
  
/*非递归后序遍历树:后序遍历,先遍历到的结点最后访问 
用两个栈,一个栈用来遍历,另一个栈保存遍历到的结点,最后一起出栈,就是后序遍历结果 
*/  
void postOrder(Node* root)  
{  
    stack<Node*> sTraverse,sVisit;  
    Node* p=NULL;  
    if(root==NULL) return;  
    sTraverse.push(root);  
    while(!sTraverse.empty())  
    {  
        p=sTraverse.top(); sTraverse.pop();  
        sVisit.push(p);  
        if(p->left) sTraverse.push(p->left);  
        if(p->right) sTraverse.push(p->right);  
    }  
    while(!sVisit.empty())  
    {  
        p=sVisit.top(); sVisit.pop();  
        cout<<p->data<<" ";  
    }  
}  
  
/*非递归后序遍历树算法:从根节点开始,只要当前节点存在,或者栈不为空,则重复下面操作: 
  (1)从当前节点开始,进栈并走左子树,直到左子树为空。 
  (2)如果栈顶节点的右子树为空,或者栈顶节点的右孩子为刚访问过的节点, 
     则退栈并访问,然后置当前节点指针为空。 
  (3)否则走右子树。 
*/  
void postOrder(Node* t)  
{  
    Node *p,*q;  
    stack<Node*> s;  
    p=t;  
    q=NULL;  
    while(p!=NULL||!s.empty())  
    {  
        while(p!=NULL)  
        {  
            s.push(p); p=p->left;  
        }  
        if(!s.empty())  
        {  
            p=s.top();  
            if((p->right==NULL) || (p->right==q))  
            {  
                cout<<p->data<<" ";  
                q=p;  
                s.pop();  
                p=NULL;  
            }  
            else p=p->right;  
        }  
    }  
}  
  
/*根节点到r节点的路径: 
后序遍历时访问到r节点时,栈中的所有的节点均为r节点的祖先,这些祖先构成根节点到r节点的路径 
*/  
void nodePath(Node* root,Node* r)  
{  
    Node *p,*q;  
    stack<Node*> s;  
    p=root;  
    q=NULL;   //q保存刚访问过的节点   
    while(p!=NULL||!s.empty())  
    {  
        while(p!=NULL)  
        {  
            s.push(p); p=p->left;  
        }  
        if(!s.empty())  
        {  
            p=s.top();  
            if( (p->right==NULL) || (p->right==q) )  
            {  
                if(p==r)  
                {  
                    while(!s.empty())  
                    {  
                        Node* t=s.top();  
                        s.pop();  
                        cout<<t->value<<" ";  
                    }  
                    return;  
                }  
                else  
                {  
                    q=p;  
                    s.pop();  
                    p=NULL;  
                }  
            }  
            else p=p->right;  
        }  
    }  
}  

 

posted @ 2012-08-04 11:52  阿凡卢  阅读(1907)  评论(0编辑  收藏  举报