#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct BinNode
{
char ch;
struct BinNode *lchlid;
struct BinNode *rchlid;
};
//先序遍历 根左右
void xianxubianli(struct BinNode *root)
{
if (NULL == root)
{
return;
}
printf("%c ", root->ch);
//递归遍历左子树
xianxubianli(root->lchlid);
xianxubianli(root->rchlid);
}
//中序遍历 左根右
void zhongxubianli(struct BinNode *root)
{
if (NULL == root)
{
return;
}
zhongxubianli(root->lchlid);
printf("%c ", root->ch);
//递归遍历左子树
zhongxubianli(root->rchlid);
}
//后序遍历 左右根
void houxubianli(struct BinNode *root)
{
if (NULL == root)
{
return;
}
houxubianli(root->lchlid);
//递归遍历左子树
houxubianli(root->rchlid);
printf("%c ", root->ch);
}
void test()
{
struct BinNode nodeA = { 'A', NULL, NULL };
struct BinNode nodeB = { 'B', NULL, NULL };
struct BinNode nodeC = { 'C', NULL, NULL };
struct BinNode nodeD = { 'D', NULL, NULL };
struct BinNode nodeE = { 'E', NULL, NULL };
struct BinNode nodeF = { 'F', NULL, NULL };
struct BinNode nodeG = { 'G', NULL, NULL };
struct BinNode nodeH = { 'H', NULL, NULL };
/*
A
B F
C G
D E H
*/
nodeA.lchlid = &nodeB;
nodeA.rchlid = &nodeF;
nodeB.rchlid = &nodeC;
nodeC.lchlid = &nodeD;
nodeC.rchlid = &nodeE;
nodeF.rchlid = &nodeG;
nodeG.lchlid = &nodeH;
printf("\n");
xianxubianli(&nodeA);
printf("\n");
printf("========\n");
zhongxubianli(&nodeA);
printf("\n");
printf("========\n");
houxubianli(&nodeA);
printf("\n");
printf("========\n");
}
//叶子节点的个数
void yezi(struct BinNode *root,int *num)
{
if (NULL == root)
{
return;
}
if (root->lchlid == NULL && root->rchlid == NULL)
{
(*num)++;
}
yezi(root->lchlid,num);
yezi(root->rchlid,num);
}
//树的高度
int gaodu(struct BinNode *root)
{
if (NULL == root)
{
return 0;
}
//左子树高度
int lgao = gaodu(root->lchlid);
//右子树高度
int rgao = gaodu(root->rchlid);
int gao = lgao > rgao ? lgao + 1 : rgao + 1;
return gao;
}
//二叉树拷贝
struct BinNode *cp(struct BinNode *root, struct BinNode **shu)
{
if (NULL == root)
{
return NULL;
}
//先拷贝左子树
struct BinNode *lchlid = cp(root->lchlid,shu);
//再拷贝右子树
struct BinNode *rchlid = cp(root->rchlid,shu);
struct BinNode *node = malloc(sizeof(struct BinNode));
node->lchlid = lchlid;
node->rchlid = rchlid;
node->ch = root->ch;
//strcpy(node->ch, root->ch);
*shu = node;
return *shu;
}
//二叉树拷贝
struct BinNode *cp1(struct BinNode *root)
{
if (NULL == root)
{
return NULL;
}
//先拷贝左子树
struct BinNode *lchlid = cp1(root->lchlid);
//再拷贝右子树
struct BinNode *rchlid = cp1(root->rchlid);
struct BinNode *node = malloc(sizeof(struct BinNode));
node->lchlid = lchlid;
node->rchlid = rchlid;
node->ch = root->ch;
//strcpy(node->ch, root->ch);
return node;
}
//释放内存
void freetree(struct BinNode *root)
{
if (NULL == root)
{
return;
}
freetree(root->lchlid);
freetree(root->rchlid);
printf("shu=%c ", root->ch);
free(root);
/*这是错误的 因为先释放左边后释放右边 即使左子树和右子树 都释放后
他们的爸爸 还是指向他们 所以直接释放就好
if ((root->lchlid == NULL) && (root->rchlid == NULL))
{
free(root);
}
*/
}
void test1()
{
struct BinNode nodeA = { 'A', NULL, NULL };
struct BinNode nodeB = { 'B', NULL, NULL };
struct BinNode nodeC = { 'C', NULL, NULL };
struct BinNode nodeD = { 'D', NULL, NULL };
struct BinNode nodeE = { 'E', NULL, NULL };
struct BinNode nodeF = { 'F', NULL, NULL };
struct BinNode nodeG = { 'G', NULL, NULL };
struct BinNode nodeH = { 'H', NULL, NULL };
/*
A
B F
C G
D E H
*/
nodeA.lchlid = &nodeB;
nodeA.rchlid = &nodeF;
nodeB.rchlid = &nodeC;
nodeC.lchlid = &nodeD;
nodeC.rchlid = &nodeE;
nodeF.rchlid = &nodeG;
nodeG.lchlid = &nodeH;
int num = 0;
yezi(&nodeA,&num);
printf("\n");
//叶子节点个数
printf("叶子节点个数num=%d\n", num);
//树的高度
int gao = gaodu(&nodeA);
printf("树的高度num=%d\n", gao);
struct BinNode *newshu = malloc(sizeof(struct BinNode));
cp(&nodeA,&newshu);
//先序遍历新拷贝的树1
printf("先序遍历新拷贝的树1\n");
xianxubianli(newshu);
printf("\n");
printf("================\n");
struct BinNode *newshu2 = cp1(&nodeA);
//先序遍历新拷贝的树2
printf("先序遍历新拷贝的树2\n");
xianxubianli(newshu2);
printf("\n");
printf("================\n");
//这个不是拷贝的 无法释放
//freetree(&nodeA);
printf("=====树1的释放顺序======\n");
freetree(newshu);
printf("\n");
printf("=====树2的释放顺序======\n");
freetree(newshu2);
printf("\n");
}
int main(void)
{
test();
printf("\n");
test1();
/*
A B C D E F G H
========
B D C E A F H G
========
D E C B H G F A
========
叶子节点个数num=3
树的高度num=4
先序遍历新拷贝的树1
A B C D E F G H
================
先序遍历新拷贝的树2
A B C D E F G H
================
=====树1的释放顺序======
shu=D shu=E shu=C shu=B shu=H shu=G shu=F shu=A
=====树2的释放顺序======
shu=D shu=E shu=C shu=B shu=H shu=G shu=F shu=A
请按任意键继续. . .
*/
system("pause");
return 0;
}
二叉树的基本遍历
最新推荐文章于 2022-11-04 22:51:50 发布