二叉树的基本遍历

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值