一、主要内容
(1)二叉树的二叉链表的创建
(2)二叉树的前、中、后序遍历的递归算法
(3)求二叉树中叶子结点数目的递归算法
(4)编写二叉树中位于后序序列第k个结点的值的算法
(5)编写算法删除二叉树中所有以值为x的结点为根的子树并释放相应空间
(6)二叉树的前/中/后序遍历的非递归算法的实现
(7)编写二叉树层序遍历的算法
二、整体代码
#include<stdio.h>
#include<stdlib.h>
//实验五
#define MAX_TREE_SIZE 100
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode* lchild;
struct BiTNode* rchild;
int flag;
}BiTNode, *BiTree;
void CreateBiTree(BiTree* T)
{
char c;
printf("请输入该结点的元素(输入','表示停止在该根结点下创建子树):");
getchar();
scanf("%c", &c);
if (c == ',')
{
*T = NULL;
return;//printf("构造了一个空树\n");
}
else
{
if (!(*T = (BiTree)malloc(sizeof(BiTNode))))
return;//printf("OVERFLOW\n");
else
{
(*T)->data = c;
//printf("%c\n", (*T)->data);
//printf("left ");
CreateBiTree(&((*T)->lchild));
//printf("right ");
CreateBiTree(&((*T)->rchild));
(*T)->flag = 0;
}
}
}
int PrintElement(ElemType c)
{
printf("%c ", c);
return 1;
}
//递归算法
int PreOrderTraverse0(BiTree T)
{
if (T)
{
//printf("!");
//先序遍历根结点
if (PrintElement(T->data))//先打印出结点的数据元素
//先序遍历左子树
if (PreOrderTraverse0(T->lchild))//向左遍历该根结点下的左子树,若T->lchild为空,返回1且继续遍历右子树
//先序遍历右子树
if (PreOrderTraverse0(T->rchild))//遍历右子树,若T->rchild也为空,仍返回1,执行if语句的的分支“return 1”
return 1;//表示以T为根节点的子树已经遍历完毕,返回父结点,继续向父节点的另一棵子树遍历
return 0;
}
else
{
//printf("?");
return 1;
}
//说明T这个子树为空,返回1进入另一棵子树遍历
}
void InOrderTraverse0(BiTree T)
{
if (T != NULL)
{
InOrderTraverse0(T->lchild);
PrintElement(T->data);
InOrderTraverse0(T->rchild);
}
}
void PostOrderTraverse0(BiTree T)
{
if (T != NULL)
{
PostOrderTraverse0(T->lchild);
PostOrderTraverse0(T->rchild);
PrintElement(T->data);
}
}
//非递归算法
void initzero(BiTree T)
{
BiTree S[MAX_TREE_SIZE];
BiTree p, q;
p = T;
int top = 0;
if (T == NULL)
{
printf("二叉树为空。\n");
return;
}
while (p != NULL)
{
p->flag = 0;
//PrintElement(p->data);
q = p->rchild;
if (q != NULL)
{
top++;
S[top] = q;
}
p = p->lchild;
if (p == NULL && top > 0)
{
p = S[top];
top--;
}
}
}
void PreOrderTraverse1(BiTree T)
{
BiTree S[MAX_TREE_SIZE];
BiTree p, q;
p = T;
int top = 0;
if (T == NULL)
{
printf("二叉树为空。\n");
return;
}
while (p != NULL)
{
PrintElement(p->data);
q = p->rchild;
if (q != NULL)
{
top++;
S[top] = q;
}
p = p->lchild;
if (p == NULL && top > 0)
{
p = S[top];
top--;
}
}
}
void InOrderTraverse1(BiTree T)
{
BiTree S[MAX_TREE_SIZE];
BiTree p = T;
int top = 0;
if (T == NULL)
{
printf("二叉树为空。\n");
return;
}
while (p != NULL || top > 0)
{
if (p != NULL)
{
S[top] = p;
top++;
p = p->lchild;
}
else
{
top--;
p = S[top];
PrintElement(p->data);
p = p->rchild;
}
}
}
void PostOrderTraverse1(BiTree T)
{
initzero(T);
BiTree S[MAX_TREE_SIZE];
BiTree p = T;
int top = 0;
if (T == NULL)
{
printf("二叉树为空。\n");
return;
}
while (1)
{
if (p != NULL)
{
S[top] = p;
top++;
p = p->lchild;
}
else
{
top--;
p = S[top];
if (p->rchild == NULL || p->flag == 1)
{
PrintElement(p->data);
p = NULL;
}
else
{
S[top] = p;
top++;
p->flag = 1;
p = p->rchild;
}
}
if (top == 0)
{
break;
}
}
}
void LeafNum(BiTree T)
{
initzero(T);
BiTree S[MAX_TREE_SIZE];
BiTree p;
p = T;
int num = 0;
int top = 0;
if (T == NULL)
{
printf("二叉树为空。\n");
return;
}
while (1)
{
if (p != NULL)
{
S[top] = p;
top++;
p = p->lchild;
}
else
{
top--;
p = S[top];
if (p->rchild == NULL || p->flag == 1)
{
if (p->rchild == NULL)
num++;
//PrintElement(p->data);
p = NULL;
}
else
{
S[top] = p;
top++;
p->flag = 1;
p = p->rchild;
}
}
if (top == 0)
{
break;
}
}
printf("叶子结点的个数为%d\n", num);
return;
}
void Function7(BiTree T,int k)
{
initzero(T);
BiTree S[MAX_TREE_SIZE];
BiTree p = T;
int top = 0;
//ElemType m[MAX_TREE_SIZE];
int i = 0;
if (T == NULL)
{
printf("二叉树为空。\n");
return;
}
while (1)
{
if (p != NULL)
{
S[top] = p;
top++;
p = p->lchild;
}
else
{
top--;
p = S[top];
if (p->rchild == NULL || p->flag == 1)
{
//PrintElement(p->data);
//m[i] = p->data;
i++;
if (k == i)
{
printf("第k个结点的值:%c\n", p->data);
return;
}
p = NULL;
}
else
{
S[top] = p;
top++;
p->flag = 1;
p = p->rchild;
}
}
if (top == 0)
{
break;
}
}
}
void delsubtree(BiTree T)
{
if (T)
{
delsubtree(T->lchild); delsubtree(T->rchild);
free(T);
}//if
}//delsubtree
void DelTree(BiTree* T, ElemType x)
{
if (*T)
{
if ((*T)->data == x)
{
delsubtree(*T);
*T = NULL;
}
else
{
DelTree(&(*T)->lchild, x);
DelTree(&(*T)->rchild, x);
}
}//if
}//DelTree
void Function8(BiTree* T,ElemType x)
{
BiTree S[MAX_TREE_SIZE];
BiTree p, q;
p = *T;
int top = 0;
if (p == NULL)
{
printf("二叉树为空。\n");
return;
}
while (p != NULL)
{
//PrintElement(p->data);
if ((p->rchild)->data == x)
{
p->rchild = NULL;
free(p->rchild);
q = NULL;
}
else
{
q = p->rchild;
}
if (q != NULL)
{
top++;
S[top] = q;
}
if ((p->lchild)->data == x)
{
free(p->lchild);
p->lchild = NULL;
}
else
{
p = p->lchild;
}
if (p == NULL && top > 0)
{
p = S[top];
top--;
}
}
}
#define MAXSIZE 100
typedef struct
{
BiTree data[MAXSIZE];
int front;
int rear;
}SqQueue;
void InitQueue(SqQueue* Q)
{
Q->front = 0;
Q->rear = 0;
}
int QueueEmpty(SqQueue* Q)//队列为空,返回1,否则返回0
{
if (Q->front == Q->rear)
return 1;
else
return 0;
}
void EnQueue(SqQueue* Q, BiTree e)
{
if ((Q->rear + 1) % MAXSIZE == Q->front)
return;//printf("队满\n");
else
{
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXSIZE;
//printf("插入完成\n");
}
}
void DeQueue(SqQueue* Q, BiTree* e)
{
if (QueueEmpty(Q))
return;//printf("队空\n");
else
{
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXSIZE;
//printf("删除完成\n");
}
}
void Function10(BiTree T)
{
BiTree p;
p = T;
SqQueue Q;
InitQueue(&Q);
if (p)
{
EnQueue(&Q, p);
}
while (!QueueEmpty(&Q))
{
DeQueue(&Q, &p);
PrintElement(p->data);
if (p->lchild)
EnQueue(&Q, p->lchild);
if (p->rchild)
EnQueue(&Q, p->rchild);
}
}
int main()
{
BiTree T = NULL;
printf("-----------------------------/功能/-------------------------\n");
printf(" 1.二叉树的二叉链表的创建\n");
printf(" 2.二叉树的前中后序遍历的递归算法\n");
printf(" 3.求二叉树中叶子结点数目的递归算法\n");
printf(" 4.求二叉树中位于后序序列第k个结点的值\n");
printf(" 5.删除二叉树中所有以值为x的结点为根的子树并释放相应空间\n");
printf(" 6.二叉树的前/中/后序遍历的非递归算法的实现\n");
printf(" 7.编写二叉树层序遍历的算法\n");
printf(" 0.退出\n");
printf("请输入需要运行的功能(1-7):");
int n = 0;
scanf("%d", &n);
int t = 0;
while (n)
{
switch (n)
{
case 1:
CreateBiTree(&T);
break;
case 2:
{
getchar();
printf("请输入遍历顺序(a.前序遍历/b.中序遍历/c.后序遍历):");
char c;
scanf("%c", &c);
if (c == 'a')
{
t = PreOrderTraverse0(T);
}
else if (c == 'b')
{
InOrderTraverse0(T);
}
else if (c == 'c')
{
PostOrderTraverse0(T);
}
printf("\n");
break;
}
case 3:
LeafNum(T);
break;
case 4:
{
int k = 0;
getchar();
printf("请输入结点的序号:");
scanf("%d", &k);
Function7(T, k);
break;
}
case 5:
{
ElemType x;
getchar();
printf("请输入结点的值:");
scanf("%c", &x);
DelTree(&T, x);
break;
}
case 6:
{
getchar();
printf("请输入遍历顺序(a.前序遍历/b.中序遍历/c.后序遍历):");
char c;
scanf("%c", &c);
if (c == 'a')
{
PreOrderTraverse1(T);
}
else if (c == 'b')
{
InOrderTraverse1(T);
}
else if (c == 'c')
{
PostOrderTraverse1(T);
}
printf("\n");
break;
}
case 7:
{
Function10(T);
printf("\n");
break;
}
default:
break;
}
printf("请继续输入需要运行的功能(1-7):");
scanf("%d", &n);
}
return 0;
}
三、总结
仅作为个人实验作业内容,如有错误请各位指正。