一、【实验目的】
1、了解树的建立方法
2、掌握树与二叉树的转化及其遍历的基本方法
3、掌握递归二叉树遍历算法的应用
二、【实验内容】
1.构造一棵药品信息树,树的形态如下图所示,打印出先序遍历、后序遍历的遍历序列。
2.编写一个层序遍历算法,利用队列结构按层次(同一层自左至右)输出树中所有的结点。
3.将树结构转化为二叉树,编写二叉树非递归中序遍历算法,并输出遍历序列。
三、【实验源代码】
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct a{
struct a* fchild;
struct a* brother;
char data[100];
int tag;
}tnode;
typedef struct {
int front, rear, count;
tnode* queue[100];
}queue;
typedef struct {
int top;
tnode* stack[100];
}s;
void initiate(s* my)
{
my->top = 0;
}
void stackpush(s*s,tnode*p)
{
s->stack[s->top++] = p;
}
void stackpop(s* s, tnode** p)
{
*p = s->stack[--s->top];
}
int stacknotempty(s* s)//返回0则为空
{
if (s->top == 0)
return 0;
return 1;
}
void init(queue* q)
{
q->count = 0;
q->front = 0;
q->rear = 0;
}
void queuepush(queue* q,tnode*p)
{
q->queue[q->rear] = p;
q->rear = (q->rear + 1) % 100;
q->count++;
}
void queuepop(queue* q, tnode** p)
{
q->count--;
*p = q->queue[q->front];
q->front = (q->front + 1) % 100;
}
tnode* fchild(tnode* p)
{
if (!p)
return NULL;
return p->fchild;
}
tnode* brother(tnode* p)
{
if (!p)
return NULL;
return p->brother;
}
int qnotempty(queue* q)//空队列返回0
{
if (q->count == 0 && q->front == q->rear)
return 0;
return 1;
}
tnode* create()
{
tnode* my;
char str[100];
scanf("%s", str);
if (strcmp(str, "#")==0)//首孩子结点为0
{
my = NULL;
}
else if (strcmp(str, "$")==0)//首兄弟结点为0
{
my = NULL;
}
else
{
my = (tnode*)malloc(sizeof(tnode));
if (my == NULL)
return NULL;
strcpy(my->data,str);
my->fchild = create();
my->brother = create();
}
return my;
}
void postorder(tnode* t)
{
if (t == NULL)
return ;
postorder(t->fchild);
postorder(t->brother);
printf("%s ", t->data);
}
void preorder(tnode*t)
{
if (t == NULL)
return ;
printf("%s ", t->data);
t->tag = 0;
preorder(t->fchild);
preorder(t->brother);
}
void layeroreder(tnode*root)
{
tnode *p,*t;
queue* q = (queue*)malloc(sizeof(queue));
init(q);
p = root;
if (p)
queuepush(q, p);
while (qnotempty(q) )
{
queuepop(q, &p);
t = p;
printf("%s ", p->data);
if (p->tag == 0)
{
p->tag = 1;
while (brother(p))
{
p = p->brother;
p->tag = 1;
queuepush(q, p);
}
}
p = t;
if (fchild(p))
{
p = p->fchild;
queuepush(q, p);
if (p->tag == 0)
{
p->tag = 1;
while (brother(p))
{
p = p->brother;
p->tag = 1;
queuepush(q, p);
}
}
}
}
return;
}
void inorder(tnode*root)
{
s* mystack=(s*)malloc(sizeof(s));
initiate(mystack);
tnode* p;
p = root;
while (stacknotempty(mystack) || p)
{
if (p)
{
stackpush(mystack, p);
p = p->fchild;
}
else
{
stackpop(mystack, &p);
printf("%s ", p->data);
p = p->brother;
}
}
}
int main()
{
tnode* tree;
tree = create();
printf("树已构建完毕\n");
printf("先序遍历的结果:");
preorder(tree);
printf("\n");
printf("后序遍历的结果:");
postorder(tree);
printf("\n");
printf("层序遍历的结果:");
layeroreder(tree);
printf("\n");
printf("一般树转化成二叉树后的中序遍历:");
inorder(tree);
return 0;
}
-
- 【实验结果】
五、【实验心得】
1.我的收获
树的建立可以通过递归,以某种序列输入各节点的值(这里我通过先序遍历),先输入当前节点的值,再构建首孩子节点的树,再构建兄弟节点的树。树转化成二叉树,就是将首孩子当作左孩子,兄弟节点当作右孩子。
2.我碰到的问题及解决办法
录入字符串时,最好用字符数组来接受,赋值时用strcpy。理解队列的性质。