注意事项:
- 使用abcd###e##c#f## 来进行先序输入。或者最后两个为空格,否则会一直提示输入。
- 重点关注层序遍历,因为其特性,所以需要一个队列数据结构来进行配合。
- 结点拥有的子树数为结点的度,度为0的结点为叶子结点,树的度是树内各结点度的最大值,二叉树即度为二的树。树中结点的最大层次称为树的深度。
- 出现半小时BUG:在创建函数定义中使用%d期待输入数字,但实际操作中输入了字母,会导致编译错误。
- 半小时BUG2:在队列的出队列函数中,没有设置如果是出列的是最后一个,将尾指针指向头指针。否则会出现尾指针是野指针的情况。
- 20分钟BUG3:如果有两个Creat函数都接受字符串输入的情况下,第一个确认输入的ENTER键会在缓冲区保留,直到第二个Creat函数接受字符时接受,导致树无法正确创建!!!用吃回车函数解决。
- 半小时BUG4:Destroy函数未正确使用递归!导致调用其的Delete函数也无法使用。
#define QElemtype BiTree
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct BiTNode
{
char data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
typedef struct QNode
{
QElemtype data;
struct QNode * next;
}QNode, *QueuePtr;
typedef struct
{
QueuePtr front, rear;
}LinkQ, *LinkQueue;
void InitQueue(LinkQueue *q);
void EnQueue(LinkQueue q, QElemtype t);
void DeQueue(LinkQueue q, QElemtype *t);
void DestroyQueue(LinkQueue *q);
int QueueEmpty(LinkQueue q);
void CreatBiTree(BiTree *t);
若二叉树非空,则依次执行以下操作
⑴ 建立根结点;
⑵ 建立左子树;
⑶ 建立右子树。
void DestroyBiTree(BiTree *t);
void DeleteChild(BiTree p, int LR);
void InsertChild(BiTree p, int LR, BiTree c);
void PreOrderTraverse(BiTree t);
void InOrderTraverse(BiTree t);
void PostOrderTraverse(BiTree t);
void LevelOrderTraverse(BiTree t);
int main()
{
BiTree t = NULL;
CreatBiTree(&t);
PreOrderTraverse(t);
printf("NULL\n");
BiTree p = t->lchild;
char ch;
while ((ch = getchar()) != '\n')
continue;
BiTree c = NULL;
printf("The second Tree is :\n");
CreatBiTree(&c);
PreOrderTraverse(c);
printf("NULL\n");
InsertChild(p, 1, c);
printf("After inserting the left Tree:\n");
PreOrderTraverse(t);
printf("NULL\n");
p = t->lchild->lchild;
DeleteChild(p, 0);
printf("The process is finish!\n");
PreOrderTraverse(t);
return 0;
}
void CreatBiTree(BiTree *t)
{
char ch;
scanf_s("%c", &ch);
if (ch == ' ')
*t = NULL;
else
{
*t = (BiTree)malloc(sizeof(BiTNode));
if (!*t)
exit(1);
(*t)->data = ch;
CreatBiTree(&((*t)->lchild));
CreatBiTree(&((*t)->rchild));
}
}
void DestroyBiTree(BiTree *t)
{
if (*t)
{
if ((*t)->lchild)
DestroyBiTree(&((*t)->lchild));
if ((*t)->rchild)
DestroyBiTree(&((*t)->rchild));
free(*t);
(*t) = NULL;
}
}
void DeleteChild(BiTree p, int LR)
{
if (LR == 0)
DestroyBiTree(&(p->lchild));
else
DestroyBiTree(&(p->rchild));
}
void InsertChild(BiTree p, int LR, BiTree c)
{
if (p)
{
if (LR == 0)
{
c->rchild = p->lchild;
p->lchild = c;
}
else
{
c->rchild = p->rchild;
p->rchild = c;
}
}
else
exit(1);
}
void PreOrderTraverse(BiTree t)
{
if (t)
{
printf("%c->", t->data);
PreOrderTraverse(t->lchild);
PreOrderTraverse(t->rchild);
}
}
void InOrderTraverse(BiTree t)
{
if (t)
{
InOrderTraverse(t->lchild);
printf("%c ", t->data);
InOrderTraverse(t->rchild);
}
}
void PostOrderTraverse(BiTree t)
{
if (t)
{
PostOrderTraverse(t->lchild);
PostOrderTraverse(t->rchild);
printf("%c ", t->data);
}
}
void LevelOrderTraverse(BiTree t)
{
LinkQ o;
LinkQueue q = &o;
QElemtype a;
if (t)
{
InitQueue(&q);
EnQueue(q, t);
while (!QueueEmpty(q))
{
DeQueue(q, &a);
printf("%c->", a->data);
if (a->lchild != NULL)
EnQueue(q, a->lchild);
if (a->rchild != NULL)
EnQueue(q, a->rchild);
}
printf("NULL\n");
DestroyQueue(&q);
}
}
void InitQueue(LinkQueue *q)
{
(*q)->front = (*q)->rear = (QueuePtr)malloc(sizeof(QNode));
(*q)->front->next = NULL;
}
void EnQueue(LinkQueue q, QElemtype t)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
p->data = t;
(*q).rear->next = p;
p->next = NULL;
(*q).rear = p;
}
void DeQueue(LinkQueue q, QElemtype *t)
{
if (q->front == q->rear)
exit(1);
QueuePtr p = (*q).front->next;
q->front->next = p->next;
(*t) = p->data;
if (q->rear == p)
q->rear = q->front;
free(p);
}
void DestroyQueue(LinkQueue *q)
{
while ((*q)->front)
{
(*q)->rear = (*q)->front->next;
free((*q)->front);
(*q)->front = (*q)->rear;
}
}
int QueueEmpty(LinkQueue q)
{
if (q->front == q->rear)
return 1;
else
return 0;
}