您的位置:首页 > 编程语言 > C语言/C++

二叉树遍历算法

2013-11-01 20:43 447 查看
原地址:http://blog.csdn.net/csdn0123/article/details/7424054

二叉树的遍历是指按照一定次序访问二叉树中的所有节点,且每个节点仅被访问一次的过程。是最基本的运算,是其他运算的基础。

     二叉树有两种存储结构:顺序存储和链式存储

    顺序存储:  (对完全二叉树来说,可以充分利用存储空间,但对于一般的二叉树,只有少数的存储单元被利用)

[cpp] view
plaincopy

typedef struct   

{  

    ElemType data[MaxSize];  

    int n;  

}SqBTree;  

  链式存储:

[csharp] view
plaincopy

typedef struct node  

{  

    ElemType data;  

    struct node *lchild;  

    struct node *rchild;  

} BTNode;  

二叉树三种递归的遍历方法:

先序遍历访问根节点→先序遍历左子树→先序遍历右子树
中序遍历中序遍历左子树→访问根节点→中序遍历右子树
后序遍历后序遍历左子树→后序遍历右子树→访问根节点
二叉树遍历的递归算法:

[cpp] view
plaincopy

void preOrder(BTNode *b)  //先序遍历递归算法  

{  

    if (b!=NULL)  

    {  

        visit(b);  

        preOrder(b->lchild);  

        preOrder(b->rchild);  

    }  

}  

void InOrder(BTNode *b)   //中序遍历递归算法  

{  

    if(b!=NULL)  

    {  

        InOrder(b->lchild);  

        visit(b);  

        InOrder(b->rchild);  

    }  

}  

void PostOrder(BTNode *b)   //后序遍历递归算法  

{  

    if(b!=NULL){  

        PostOrder(b->lchild);  

        PostOrder(b->rchild);  

        visit(b);  

    }  

}  

二叉树非递归遍历算法:

有两种方法:①用栈存储信息的方法  ②增加指向父节点的指针的方法    暂时只介绍下栈的方法

先序遍历:

[cpp] view
plaincopy

void PreOrder(BTNode *b)  

{  

    Stack s;  

    while(b!=NULL||!s.empty())  

    {  

        if(b!=NULL){  

            visit(b);  

            s.push(b);  

            b=b->left;  

        }  

        else{  

            b=s.pop();  

            b=b->right;  

        }  

    }  

}  

中序遍历:

[cpp] view
plaincopy

void InOrder(BTNode *b){  

    Stack s;  

    while(b!=NULL||!s.empty()){  

        if (b!=NULL)  

        {  

            s.push(b);  

            s=s->left  

        }  

        if(!s.empty()){  

            b=s.pop();  

            visit(b);  

            b=b->right;  

        }  

    }  

}  

后序遍历:

[cpp] view
plaincopy

void PostOrder(BTNode *b){  

    Stack s;  

    while(b!=NULL){  

        s.push(b);  

    }  

    while(!s.empty()){  

        BTNode* node=s.pop();  

        if(node->bPushed){  

            visit(node);  

        }  

        else{  

            s.push(node);  

            if(node->right!=NULL){  

                node->right->bPushed=false;  

                s.push(node->right);  

            }  

            if(node->left!=NULL){  

                node->left->bpushed=false;  

                s.push(node->left);  

            }  

        node->bPushed=true;  //如果标识位为true,则表示入栈  

        }         

    }  

}  

层次遍历算法:(用队列的方法)

[cpp] view
plaincopy

void levelOrder(BTNode *b){  

    Queue Q;  

    Q.push(b);  

    while(!Q.empty()){  

        node=Q.front();  

        visit(node);  

        if(NULL!=node->left){  

            Q.push(node->left);  

        }  

        if(NULL!=right){  

            Q.push(node->right);  

        }  

    }  

}<span style=""></span>  

已知先序和中序求后序的算法:(已知后序和中序求先序的算法类似,但已知先序和后序无法求出中序)

[cpp] view
plaincopy

int find(char c,char A[],int s,int e) /* 找出中序中根的位置。 */  

{  

    int i;  

    for(i=s;i<=e;i++)  

    if(A[i]==c) return i;  

}  

/* 其中pre[]表示先序序,pre_s为先序的起始位置,pre_e为先序的终止位置。 */  

/* 其中in[]表示中序,in_s为中序的起始位置,in_e为中序的终止位置。 */  

/* pronum()求出pre[pre_s~pre_e]、in[in_s~in_e]构成的后序序列。 */  

void pronum(char pre[],int pre_s,int pre_e,char in[],int in_s,int in_e)  

{  

    char c;  

    int k;  

    if(in_s>in_e) return ; /* 非法子树,完成。 */  

    if(in_s==in_e){printf("%c",in[in_s]); /* 子树子仅为一个节点时直接输出并完成。 */  

     return ;  

    }  

    c=pre[pre_s]; /* c储存根节点。 */  

    k=find(c,in,in_s,in_e); /* 在中序中找出根节点的位置。 */  

    pronum(pre,pre_s+1,pre_s+k-in_s,in,in_s,k-1); /* 递归求解分割的左子树。 */  

    pronum(pre,pre_s+k-in_s+1,pre_e,in,k+1,in_e); /* 递归求解分割的右子树。 */  

    printf("%c",c); /* 根节点输出。 */  

}  

main()  

{  

    char pre[]="abdc";  

    char in[]="bdac";  

    printf("The result:");  

    pronum(pre,0,strlen(in)-1,in,0,strlen(pre)-1);  

    getch();  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  CC++ 算法 二叉树