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

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

//二叉树
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;
        }
    }
}


判断二叉树是否平衡、是否完全二叉树、是否二叉排序树

http://blog.csdn.net/luxiaoxun/article/details/7537022

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值