已知某二叉树采用广义表形式作为输入,请写一个非递归算法,建立二叉树的二叉链表存储结构。采用广义表形式表示二叉树的约定如下:
(1)表中的一个字母表示一个结点的数据信息;
(2)每个根节点作为由子树构成的表的名字放在表的前面;
(3)每个结点的左子树与右子树之间用逗号分开;如果只有右子树而无左子树,则逗号不能省略;
(4)整个广义表的末尾由一个特殊符号‘@’作为表的结束标志。
A(B(D),C(F(,E),G))@
表示一棵二叉树,该二叉树的根节点为A,其左孩子结点为B,右孩子结点为C,而D是B的左孩子结点,F和G分别是C的左右结点。E是F的右孩子结点。这课二叉树的图形表示
如图所示
本题类似于算术表达式求值和先序遍历的非递归过程。主要问题是建立某结点的左子树后,如何建立该结点的右子树。为此设置一个栈,用来存放根结点的指针,便于构造二叉树。这里采用栈是因为在顺序读取广义表所表示的二叉树结点具有后进先出的特性。
算法步骤:
依次读取广义表中的字符,根据不同情况按照以下方式处理:
(1)遇到左括号,可能接下来读取的元素是左孩子,需要将双亲结点入栈,同时将标志k置为1;
(2)遇到逗号,下一个读取的元素一定是右孩子,将标志置为2;
(3)遇到右括号,表明当前层读取结束,需要回退到上一层,上一层的栈元素将成为新的双亲结点;
(4)遇到字符,创建一个新结点,将当前字符ch存入数据域,然后将该结点插入对应的子树中。根据k的值进行以下处理:
①k为1,则使该结点成为栈顶元素结点的左孩子结点;
②k为2,则使该结点成为栈顶元素结点的右孩子结点。
code
#include #include #include typedef char DataType;
#define MAXSIZE 200
using namespace std;
typedef struct BiTnode
{
DataType data;
struct BiTnode *lchild, *rchild;
}*BiTree,BitNode;
int CreateBiTree(BiTree *T, DataType *str);
void DispBTNode(BiTree T);
int CreateBiTree(BiTree *T, DataType *str)
{
BiTree S[MAXSIZE], p = NULL;
int top = 0, k = 0, j = 0;
char ch;
*T = NULL;
ch = str[j];
while (ch!='@')
{
switch (ch)
{
case '(':
S[top++] = p;
k = 1;
break;
case ')':
top--;
break;
case ',':
k = 2;
break;
default:
p = (BiTree)malloc(sizeof(BitNode));
p->data = ch;
p->lchild = p->rchild = NULL;
if (*T==NULL)
{
*T = p;
}
else
{
switch (k)
{
case 1:
S[top - 1]->lchild = p;
break;
case 2:
S[top - 1]->rchild = p;
break;
}
}
break;
}
ch = str[++j];
}
return 1;
}
void main()
{
int n, len = 0;
char ch, str[MAXSIZE];
BiTree T;
cout << "请输入广义表,以‘@’结束:" << endl;
while ((ch=getchar())!='\n')
{
str[len++] = ch;
}
n = CreateBiTree(&T, str);
if (n==1)
{
cout << "创建成功!" << endl;
}
else
{
cout << "创建失败!" << endl;
}
DispBTNode(T);
system("pause");
}
void DispBTNode(BiTree T)
{
BitNode *qu[MAXSIZE];
BitNode *p;
int front, rear, n;
n = 0;
front = rear = 0;
qu[rear++] = NULL;
p = T;
if (p!=NULL)
{
qu[rear++] = p;
}
do
{
p = qu[front++];
if (p==NULL)
{
qu[rear++] = NULL;
n++;
printf("\n");
}
else
{
cout << "第" << n << "层:" << p->data << endl;
if (p->lchild!=NULL)
{
qu[rear++] = p->lchild;
}
if (p->rchild!=NULL)
{
qu[rear++] = p->rchild;
}
}
} while (front!=rear-1);
}
结果: