假定建立树的存储结构采用标准形式。建立树的存储结构就是在内存中生成一棵树的标准形式的存储映像,即三叉链表。
在树的生成算法中,需要设置两个堆栈,一个用来存储指向根结点的指针,以便孩子结点向双亲结点链接之用,另一个用来存贮待链接的孩子结点的序号,以便能正确地链接到双亲结点的指针域。假定这两个栈分别用s和k表示,s和k栈的深度不会大于整个树的深度。
按层遍历定义为:先访问第一层结点(即树根结点),再从左到右访问第二层结点,依次按层访问,直到全树中的所有结点都被访问为止,或者说直到访问完最深一层结点为止。在树的按层遍历算法中,需要设置一个队列,假定用q表示,算法开始时将q初始化为空,接着若树根指针不为空则人队;然后每从队列中删除一个元素(即为指向结点的指针)时,都输出它的值并且依次使非空的孩子指针入队,这样反复进行下去,直到队列为空时止。
队列结构定义参考前文
.h文件:
/*广义树(三叉树)*/
#include <iostream>
#include <strstream>
using namespace std;
struct GTreeNode
{
char data;
GTreeNode *t[3]; //用来分别存储指向第1、第2和第3个孩子结点的指针
};
typedef struct GTreeNode* ElemType;
const int QueueMaxSize = 50;
struct Queue
{
ElemType queue[QueueMaxSize];
int front;
int rear;
};
#include "queue.h"
//树的生成
void CreateGTree(GTreeNode* >, char *a)
{
GTreeNode *s[10]; //用来存储三叉树中的结点指针
int k[10]; //用来存储孩子结点链接到双亲结点指针域的序号的栈
int top = -1; //两个栈的栈顶指针
GT = NULL;
GTreeNode *p;
istrstream ins(a);
char ch;
ins>>ch;
while(ch != '@')
{
switch(ch)
{
case '(':
top++;
s[top] = p; //使得待读入的孩子结点将链接到s栈顶结点的第一个指针域
k[top] = 0;
break;
case ')':
top--;
break;
case ',':
k[top]++; //待读入的孩子结点将链接到s栈顶结点的下一个指针域
break;
default: //此处处理的必然是字符元素
p = new GTreeNode;
p->data = ch;
for(int i = 0; i < 3; i++)
p->t[i] = NULL;
if(GT == NULL)
GT = p;
else
s[top]->t[k[top]] = p;
break;
}
ins>>ch;
}
}
//树的先序遍历
void PreRoot(GTreeNode *GT)
{
if(GT != NULL)
{
cout<<GT->data<<" ";
for(int i = 0; i < 3; i++)
PreRoot(GT->t[i]);
}
}
//树的按层遍历
void LayerOrder(GTreeNode *GT)
{
Queue q;
InitQueue(q);
GTreeNode *p;
if(GT != NULL)
QInsert(q,GT);
while(!QueueEmpty(q))
{
p = QDelete(q);
cout<<p->data<<" ";
for(int i = 0; i < 3; i++)
{
if(p->t[i] != NULL)
QInsert(q,p->t[i]);
}
}
}
/*
A(B(D,E(H,I),F),C(G))@
*/