本程序实现二叉树的如下功能
1、以先序序列和中序序列构造二叉树
2、以层序序列和中序序列构造二叉树
3、先序遍历、中序遍历、后序遍历、层序遍历
4、求二叉树高度
5、验证这个二叉树是否具备这样的性质:任何一个子树中的结点集合,树根结点的值总是最小。(按字母序)
6、拷贝二叉树
7、将二叉树左右子树交换
8、销毁二叉树
9、删除值为x的节点及其全部子孙
binary_tree.h文件
注:queue.h文件在这里
#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "queue.h"
#define SIZE_bt 1024
struct bt
{
char data;
struct bt *lchild, *rchild;
};
struct bt *PreInBuild(char *pre, char *in);//以先序序列和中序序列构造二叉树
struct bt *LevelInBuild(char *level, char *in);//以层序序列和中序序列构造二叉树
void PreOdTraversal(struct bt *t, char *result);//先序遍历
void InOdTraversal(struct bt *t, char *result);//中序遍历
void PostOdTraversal(struct bt *t, char *result);//后序遍历
void LevelOdTraversal(struct bt *t, char *result);//层序遍历
int Height(struct bt *t);//求二叉树高度
bool IsRootSmallest(struct bt *t);//验证这个二叉树是否具备这样的性质:任何一个子树中的结点集合,树根结点的值总是最小。(按字母序)
struct bt *CopyTree(struct bt *source);//拷贝二叉树
void ExchangeLRChild(struct bt *t);//将二叉树左右子树交换
void DestroyTree(struct bt *t);//销毁二叉树
void Cut(struct bt *t, char x);//删除值为x的节点及其全部子孙
#endif /* __BINARY_TREE_H__ */
binary_tree.c文件
#include "binary_tree.h"
char traversal_result[SIZE_bt];//用于存储遍历结果
struct bt *PreInBuild(char *pre, char *in)
{
int in_len;
char *c, *d;
char *lin, *rin, *lpre, *rpre;
struct bt *root;
root = (struct bt *)malloc(sizeof(struct bt));
if (root == NULL)
exit(-1);//内存不足
root->lchild = NULL;
root->rchild = NULL;
if (*pre == '\0' && *in == '\0')
return NULL;
if (*pre == '\0' || *in == '\0')
exit(2);//未知错误
root->data = *pre;
in_len = strlen(in);//截断in之前先记录其长度
for (c = in; *c != '\0'; c++)
if (*c == root->data)//分割左、右子树的中序序列
{
*c = '\0';
break;
}
if ((c - in) == in_len)
exit(1);//中序序列中未出现根节点
lin = in;
rin = c + 1;
//拷贝左子树的前序序列
lpre = (char *)malloc(strlen(lin) + 1);
d = lpre;
for (c = pre + 1; (c - pre - 1) < strlen(lin); c++)
*d++ = *c;
*d = '\0';
rpre = c;
root->lchild = PreInBuild(lpre, lin);
root->rchild = PreInBuild(rpre, rin);
return root;
}
struct bt *LevelInBuild(char *level, char *in)
{
int in_len;
char *c, *d, *e, *f;//遍历字符串需要的指针
char *lin, *rin, *llevel, *rlevel;
struct bt *root;
root = (struct bt *)malloc(sizeof(struct bt));
if (root == NULL)
exit(-1);//内存不足
root->lchild = NULL;
root->rchild = NULL;
if (*level == '\0' && *in == '\0')
return NULL;
if (*level == '\0' || *in == '\0')
exit(2);//未知错误
root->data = *level;
in_len = strlen(in);//截断in之前先记录其长度
for (c = in; *c != '\0'; c++)
if (*c == root->data)
{
*c = '\0';
break;
}
if ((c - in) == in_len)
exit(1);//中序序列中未出现根节点
lin = in;
rin = c + 1;
llevel = (char *)malloc(strlen(lin) + 1);
rlevel = (char *)malloc(strlen(rin) + 1);
//把层序序列中左子树和右子树的部分按原来的顺序分离开
d = lin;
e = llevel;
f = rlevel;
for (c = level + 1; *c != '\0'; c++)
{
for (d = lin; *d != '\0'; d++)
if (*d == *c)
{
*e++ = *c;
break;
}
if (*d == '\0')
//说明遍历完左子树的所有元素都没有找到与c相同的元素,说明c在右子树中
*f++ = *c;
}
*e = '\0';
*f = '\0';
//分离完毕
root->lchild = LevelInBuild(llevel, lin);
root->rchild = LevelInBuild(rlevel, rin);
return root;
}
static void PreOrder(struct bt *t, char *result, int *p)
{
if (t == NULL)
return;
if (*p == SIZE_bt)
exit(-1);//储存遍历结果的数组溢出
result[(*p)++] = t->data;
PreOrder(t->lchild, result, p);
PreOrder(t->rchild, result, p);
}
void PreOdTraversal(struct bt *t, char *result)
{
int pos = 0;
//为了避免函数在递归调用时记录位置信息的变量被反复初始化,需要将递归部分单独写为一个函数
PreOrder(t, result, &pos);
result[pos] = '\0';
}
static void InOrder(struct bt *t, char *result, int *p)
{
if (t == NULL)
return;
if (*p == SIZE_bt)
exit(-1);//储存遍历结果的数组溢出
InOrder(t->lchild, result, p);
result[(*p)++] = t->data;
InOrder(t->rchild, result, p);
}
void InOdTraversal(struct bt *t, char *result)
{
int pos = 0;
//为了避免函数在递归调用时记录位置信息的变量被反复初始化,需要将递归部分单独写为一个函数
InOrder(t, result, &pos);
result[pos] = '\0';
}
static void PostOrder(struct bt *t, char *result, int *p)
{
if (t == NULL)
return;
if (*p == SIZE_bt)
exit(-1);//储存遍历结果的数组溢出
PostOrder(t->lchild, result, p);
PostOrder(t->rchild, result, p);
result[(*p)++] = t->data;
}
void PostOdTraversal(struct bt *t, char *result)
{
int pos = 0;
//为了避免函数在递归调用时记录位置信息的变量被反复初始化,需要将递归部分单独写为一个函数
PostOrder(t, result, &pos);
result[pos] = '\0';
}
static void LevelOrder(struct bt *t, struct queue *q, char *result, int *p)
{
struct bt *m;
InQueue(q, t);
while (!IsEmptyQueue(q))
{
if (*p == SIZE_bt)
exit(-1);//储存遍历结果的数组溢出
m = OutQueue(q);
if (m != NULL)
{
result[(*p)++] = m->data;
InQueue(q, m->lchild);
InQueue(q, m->rchild);
}
}
}
void LevelOdTraversal(struct bt *t, char *result)
{
int pos = 0;
struct queue *q;
q = InitQueue();
LevelOrder(t, q, result, &pos);
DestroyQueue(q);
result[pos] = '\0';
}
int Height(struct bt *t)
{
int height, lheight, rheight;
if (t == NULL)
return 0;
lheight = Height(t->lchild);
rheight = Height(t->rchild);
return (lheight > rheight ? lheight : rheight) + 1;
}
static void ChangeRootSmallestFlag(struct bt *t, bool *flag)
{
if (*flag == false)
return;
if (t == NULL)
return;
if (t->lchild == NULL && t->rchild == NULL)
return;
else if (t->lchild == NULL)
{
if (t->data > t->rchild->data)
{
*flag = false;
return;
}
}
else if (t->rchild == NULL)
{
if (t->data > t->lchild->data)
{
*flag = false;
return;
}
}
else if (t->data > t->lchild->data || t->data > t->rchild->data)
{
*flag = false;
return;
}
ChangeRootSmallestFlag(t->lchild, flag);
ChangeRootSmallestFlag(t->rchild, flag);
}
bool IsRootSmallest(struct bt *t)
{
bool root_smallest_flag = true;
ChangeRootSmallestFlag(t, &root_smallest_flag);
return root_smallest_flag;
}
struct bt *CopyTree(struct bt *source)
{
//利用源二叉树的先序和中序序列构造目标二叉树,达到拷贝二叉树的目的
char *pre, *in;
struct bt *dest;
PreOdTraversal(source, traversal_result);
pre = (char *)malloc(strlen(traversal_result) + 1);
strcpy(pre, traversal_result);
InOdTraversal(source, traversal_result);
in = (char *)malloc(strlen(traversal_result) + 1);
strcpy(in, traversal_result);
dest = PreInBuild(pre, in);
free(pre);
free(in);
return dest;
}
void ExchangeLRChild(struct bt *t)
{
struct bt *temp;
if (t == NULL)
return;
temp = t->lchild;
t->lchild = t->rchild;
t->rchild = temp;
ExchangeLRChild(t->lchild);
ExchangeLRChild(t->rchild);
}
void DestroyTree(struct bt *t)
{
//通过层序遍历销毁二叉树
struct bt *m;
struct queue *q;
q = InitQueue();
InQueue(q, t);
while (!IsEmptyQueue(q))
{
m = OutQueue(q);
if (m != NULL)
{
InQueue(q, m->lchild);
InQueue(q, m->rchild);
free(m);
}
}
DestroyQueue(q);
}
void Cut(struct bt *t, char x)
{
struct bt *to_destory;
if (t == NULL)
return;
if (t->lchild == NULL && t->rchild == NULL)
return;
else if (t->lchild == NULL)
{
if (t->rchild->data == x)
{
to_destory = t->rchild;
t->rchild = NULL;
DestroyTree(to_destory);
}
}
else if (t->rchild == NULL)
{
if (t->lchild->data == x)
{
to_destory = t->lchild;
t->lchild = NULL;
DestroyTree(to_destory);
}
}
else if (t->lchild->data == x)
{
to_destory = t->lchild;
t->lchild = NULL;
DestroyTree(to_destory);
}
else if (t->rchild->data == x)
{
to_destory = t->rchild;
t->rchild = NULL;
DestroyTree(to_destory);
}
Cut(t->lchild, x);
Cut(t->rchild, x);
}
main.c文件
#include "binary_tree.h"
int main()
{
extern char traversal_result[SIZE_bt];
char traversal[SIZE_bt], in[SIZE_bt];//traversal为除中序遍历以外的任意遍历
struct bt *tree1, *tree2;
printf("Enter level-order traversal:");
scanf("%s", traversal);
getchar();
printf("Enter in-order traversal:");
scanf("%s", in);
getchar();
putchar('\n');
tree1 = LevelInBuild(traversal, in);
tree2 = CopyTree(tree1);
ExchangeLRChild(tree2);
printf("Tree 1:\n");
PreOdTraversal(tree1, traversal_result);
printf("Pre-order traversal:%s\n", traversal_result);
InOdTraversal(tree1, traversal_result);
printf("In-order traversal:%s\n", traversal_result);
PostOdTraversal(tree1, traversal_result);
printf("Post-order traversal:%s\n", traversal_result);
LevelOdTraversal(tree1, traversal_result);
printf("Level-order traversal:%s\n", traversal_result);
printf("Height:%d\n", Height(tree1));
printf("Have quality:%s\n", IsRootSmallest(tree1) ? "YES." : "NO.");
printf("\nTree 2:\n");
PreOdTraversal(tree2, traversal_result);
printf("Pre-order traversal:%s\n", traversal_result);
InOdTraversal(tree2, traversal_result);
printf("In-order traversal:%s\n", traversal_result);
PostOdTraversal(tree2, traversal_result);
printf("Post-order traversal:%s\n", traversal_result);
LevelOdTraversal(tree2, traversal_result);
printf("Level-order traversal:%s\n", traversal_result);
printf("\nEnter a node to cut:");
Cut(tree1, getchar());
printf("Tree 1(after cut):\n");
PreOdTraversal(tree1, traversal_result);
printf("Pre-order traversal:%s\n", traversal_result);
InOdTraversal(tree1, traversal_result);
printf("In-order traversal:%s\n", traversal_result);
PostOdTraversal(tree1, traversal_result);
printf("Post-order traversal:%s\n", traversal_result);
LevelOdTraversal(tree1, traversal_result);
printf("Level-order traversal:%s\n", traversal_result);
DestroyTree(tree1);
DestroyTree(tree2);
system("pause");
return 0;
}
来源:CSDN
作者:Nathaniel_039
链接:https://blog.csdn.net/liuzhaoze2000/article/details/103246469