トラバースバイナリツリー - 非再帰的なアルゴリズム

バイナリツリーの構築

         A
        / \
       B    C
      / \  / \
     D   E F  G
    前序:ABDECFG
    中序:DBEAFCG
    后序:DEBFGCA

上述した第1の実施形態は、完全なバイナリツリートラバーサル順序(再帰的に)入力を利用することができる、など(「#」は空のツリーを表す)以下:

void CreateBiTree(BiTree *T)
{
    TElemType e;
    
    if ((e=getchar()) == '#')
    {
        *T = NULL;
    }
    else
    {
        *T = (BiTree) malloc(sizeof(BiTNode));
        if (!T)
        {
            exit(0);
        }
        (*T)->data = e;
        CreateBiTree(&(*T)->lchild);    //创建左子树
        CreateBiTree(&(*T)->rchild);    //创建右子树
    }
}

注文トラバーサル(非再帰的アルゴリズム)に

原理:順次アクセス権サブツリー次いで、左サブツリーバイナリツリーにアクセスし、スタックに格納されたノードへのポインタ、ポインタが空である場合、左サブツリーのアクセスが完了し、この場合は、脱積層データ出力ノードであるべきです;

上記バイナリツリートラバーサル順序で、例えば、次のトラバース(推奨される制御コード解析)。

  1. ノードA、B、Dスタック、スタック要素{A、B、D]
  2. 左の部分木のノードDは、積層DE-次いで、Dを出力空である、要素のスタック[A、B]
  3. 右の部分木、Dが空の右の部分木、スタック要素{A、B}にD
  4. スタック解除続ける、即ち、Bスタック要素の出力[A]
  5. アクセス権サブツリーB E、E、要素[A、E]のスタックをプッシュ
  6. アクセスEは、サブツリーが空である左、引退したスタック出力スタック要素E [A]
  7. 出力スタック要素が空である、スタックオフ[]内のアクセス権のサブツリーE A
  8. アクセス権サブツリーA、C、Fスタックスタック要素[C、F]以内
  9. Fは、サブツリーが空である左、脱積層出力F、素子のスタック[C]
  10. スタックアクセス権サブツリーG [G]におけるC素子
  11. Gは空であり、脱積層スタック要素[G]を出力するサブツリーを残し
  12. このとき、ノードポインタがNULLであり、また、スタックが空である、トラバースの端

コード:

void InorderTraverse(BiTree T,Stack *s)
{
    BiTree P=T;
    while(P||s->stacksize!=0)
    {
        if(P)
        {
            Push(s, P);
            P=P->lchild;
        }
        else
        {
            P=Pop(s);
            printf("%c ",P->data);
            P=P->rchild;
        }
    }
}

予約限定(非再帰的アルゴリズム)

上の異なる位置にそのコード出力以外基本的に同じで思想思想配列先行順走査。

void preOrderTraverse(BiTree T,Stack *s)
{
    BiTree p=T;
    while(p||s->stacksize!=0)
    {
        if(p)
        {
            printf("%c ",p->data);
            Push(s, p);
            p=p->lchild;
        }
        else
        {
            p=Pop(s);
            p=p->rchild;
        }
    }
}

トラバーサル:

  1. 出力A、プッシュ要素のスタック[A]

  2. 出力B、Bは要素のスタックをプッシュ[A、B]

  3. D出力、プッシュスタック要素D [A、B、D]

  4. Dスタック解除出力E、Eは、要素{A、B、E]のスタックをプッシュ

  5. Eスタック解除、出力C、Cの要素のスタックをプッシュ[A、B、C}

  6. 出力F、Fは、要素のスタックをプッシュ[A、B、C、F]

  7. Fスタック解除、出力G、G、要素{A、B、C、G]のスタックをプッシュ

  8. 右サブツリーG、C、B、A、順次、スタック空であります

後順(非再帰的アルゴリズム)

左右、根、およびより複雑なシーケンス、配列比較にを後順、最初のオーダーを後順は、子供たちは隣接する出力のルートノードが残されているので、最終的な出力は、行きがけルート結び目が必要ですポイントは、あなたが注文トラバーサルが完了した後、さらにスタックを用いて、右のサブツリー、次のアルゴリズムを最初にアクセスする必要があります。

void PostOrderTraverse(BiTree T,Stack *s1,Stack *s2)
{
    BiTree p=T;
    while(p||s1->stacksize!=0)
    {
        if(p)
        {
            Push(s1,p);
            Push(s2,p);
            p=p->rchild;
        }
        else
        {
            p=Pop(s1);
            p=p->lchild;
        }
    }
    while(s2->stacksize!=0)
    {
        p=Pop(s2);
        printf("%c ",p->data);
    }
}

トラバーサル:

  1. A、C、Gスタックスタック1 [A、C、G] [2つのスタックA、C、G]
  2. G後退、F [1つのプッシュA、C、F [2]スタックA、C、G、F]
  3. F、Cバック、B [1つのプッシュA、B [2]スタックA、C、G、F、B]
  4. プッシュ[1 E A、B、E [2]スタックA、C、G、F、B、E]
  5. E後退、D [1プッシュA、B、D [2]スタックA、C、G、F、B、E、D]
  6. 出力スタック2、すなわち、後続のシーケンス

このアルゴリズムは、より多くのストレージスペースを消費して、すべてのノードは、スタックにバイナリツリーを持っていることが必要です

完全なコード:

#include <stdio.h>
#include<stdlib.h>

typedef char TElemType;
//树结构
typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

//栈结构
typedef struct Stack
{
    BiTree  date;
    int stacksize;  //记录元素个数
    struct Stack *next;
    struct Stack *base;  //栈底指针
    struct Stack *top;  //栈顶指针
}Stack;


//栈初始化
void InitStack(Stack *s)
{
    s->stacksize=0;
    s->base=NULL;
    s->top=s->base;
}

//插入数据
void Push(Stack *s,BiTree T)
{
        Stack *p;
        p=(Stack *)malloc(sizeof(Stack));
        if(!p)
            exit(0);
        p->date=T;
        if(s->stacksize==0)  //当插入第一个元素时,指针的变化
        {
            s->base=p;    //赋给栈底指针
            s->top=p;
            p->next=NULL;
        }
        else
        {
            p->next=s->top;
            s->top=p;
            
        }
        s->stacksize++;
}


//删除并返回栈顶元素
BiTree Pop(Stack *s)
{
    BiTree t;
    Stack *p;
    p=s->top;
    t=p->date;
    s->top=p->next;
    free(p);
    s->stacksize--;
    return t;
}

/*构建二叉树*/
void CreateBiTree(BiTree *T)
{
    TElemType e;
    
    if ((e=getchar()) == '#')
    {
        *T = NULL;
    }
    else
    {
        *T = (BiTree) malloc(sizeof(BiTNode));
        if (!T)
        {
            exit(0);
        }
        (*T)->data = e;
        CreateBiTree(&(*T)->lchild);    //创建左子树
        CreateBiTree(&(*T)->rchild);    //创建右子树
    }
}

//中序遍历(非递归)
void InorderTraverse(BiTree T,Stack *s)
{
    BiTree P=T;
    while(P||s->stacksize!=0)
    {
        if(P)
        {
            Push(s, P);
            P=P->lchild;
        }
        else
        {
            P=Pop(s);
            printf("%c ",P->data);
            P=P->rchild;
        }
    }
}

//先序遍历(非递归)
void preOrderTraverse(BiTree T,Stack *s)
{
    BiTree p=T;
    while(p||s->stacksize!=0)
    {
        if(p)
        {
            printf("%c ",p->data);
            Push(s, p);
            p=p->lchild;
        }
        else
        {
            p=Pop(s);
            p=p->rchild;
        }
    }
}

//后序遍历
void PostOrderTraverse(BiTree T,Stack *s1,Stack *s2)
{
    BiTree p=T;
    while(p||s1->stacksize!=0)
    {
        if(p)
        {
            Push(s1,p);
            Push(s2,p);
            p=p->rchild;
        }
        else
        {
            p=Pop(s1);
            p=p->lchild;
        }
    }
    while(s2->stacksize!=0)
    {
        p=Pop(s2);
        printf("%c ",p->data);
    }
}

int main()
{
    printf("请输入二叉树,#代表空树:\n");
    BiTree T;
    Stack stack1,stack2,*p1,*p;
    p=&stack1;p1=&stack2;
    InitStack(p);
    InitStack(p1);
    CreateBiTree(&T);
    printf("前序遍历结果为:");
    preOrderTraverse(T, p);
    printf("\n");
    printf("中序遍历结果为:");
    InorderTraverse(T, p);
    printf("\n");
    printf("后序遍历结果为:");
    PostOrderTraverse(T, p,p1);
    printf("\n");
    return 0;
}
/* 测试
ABD##E##CF##G##
前序遍历结果为:A B D E C F G 
中序遍历结果为:D B E A F C G 
后序遍历结果为:D E B F G C A 
Program ended with exit code: 0
*/

追伸:私はあなたが助けの少しを持つことができ、この記事を願って、このブログ詳細な回数、書き込みの過程では、コードのより深い理解を持っているだけでなく、全体のトラバーサルのより深い理解を知りません

おすすめ

転載: www.cnblogs.com/zhulmz/p/11861058.html