バイナリツリーの構築
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); //创建右子树
}
}
注文トラバーサル(非再帰的アルゴリズム)に
原理:順次アクセス権サブツリー次いで、左サブツリーバイナリツリーにアクセスし、スタックに格納されたノードへのポインタ、ポインタが空である場合、左サブツリーのアクセスが完了し、この場合は、脱積層データ出力ノードであるべきです;
上記バイナリツリートラバーサル順序で、例えば、次のトラバース(推奨される制御コード解析)。
- ノードA、B、Dスタック、スタック要素{A、B、D]
- 左の部分木のノードDは、積層DE-次いで、Dを出力空である、要素のスタック[A、B]
- 右の部分木、Dが空の右の部分木、スタック要素{A、B}にD
- スタック解除続ける、即ち、Bスタック要素の出力[A]
- アクセス権サブツリーB E、E、要素[A、E]のスタックをプッシュ
- アクセスEは、サブツリーが空である左、引退したスタック出力スタック要素E [A]
- 出力スタック要素が空である、スタックオフ[]内のアクセス権のサブツリーE A
- アクセス権サブツリーA、C、Fスタックスタック要素[C、F]以内
- Fは、サブツリーが空である左、脱積層出力F、素子のスタック[C]
- スタックアクセス権サブツリーG [G]におけるC素子
- Gは空であり、脱積層スタック要素[G]を出力するサブツリーを残し
- このとき、ノードポインタが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;
}
}
}
トラバーサル:
出力A、プッシュ要素のスタック[A]
出力B、Bは要素のスタックをプッシュ[A、B]
D出力、プッシュスタック要素D [A、B、D]
Dスタック解除出力E、Eは、要素{A、B、E]のスタックをプッシュ
Eスタック解除、出力C、Cの要素のスタックをプッシュ[A、B、C}
出力F、Fは、要素のスタックをプッシュ[A、B、C、F]
Fスタック解除、出力G、G、要素{A、B、C、G]のスタックをプッシュ
右サブツリー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);
}
}
トラバーサル:
- A、C、Gスタックスタック1 [A、C、G] [2つのスタックA、C、G]
- G後退、F [1つのプッシュA、C、F [2]スタックA、C、G、F]
- F、Cバック、B [1つのプッシュA、B [2]スタックA、C、G、F、B]
- プッシュ[1 E A、B、E [2]スタックA、C、G、F、B、E]
- E後退、D [1プッシュA、B、D [2]スタックA、C、G、F、B、E、D]
- 出力スタック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
*/
追伸:私はあなたが助けの少しを持つことができ、この記事を願って、このブログ詳細な回数、書き込みの過程では、コードのより深い理解を持っているだけでなく、全体のトラバーサルのより深い理解を知りません