二叉树之链式结构

目录

二叉树的创建

二叉树的遍历

前序遍历

中序遍历

后序遍历

层序遍历

二叉树的节点个数

二叉树叶子节点个数 

二叉树的高度 

二叉树第k层节点个数

二叉树中寻找元素

二叉树的的销毁


需要我前面的基础,递归要熟

二叉树的创建

这个就简单了,自己手动创建,后面再讲更好的方式创建

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;
BTNode* BuyNode(int k)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	newnode->data = k;
	newnode->left = NULL;
	newnode->right = NULL;

}
BTNode* CreatBinaryTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	return node1;
}

 

二叉树的遍历

前序遍历

根结点 -> 左子树 -> 右子树

这个前序遍历是(N代表空): 1  2  3  N  N  N  4  5  N  N  6  N  N

前序遍历的实现

void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	printf("%d ",root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

按序号看 

 

中序遍历

同理

左子树-> 根节点 -> 右子树

void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	
	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}

按上面画图就好理解了

后序遍历

左子树 -> 右子树 -> 根节点

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}

 

层序遍历

用什么遍历呢?

用队列好,上一层出时带它的左右孩子


void LevelOrdrt(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root == NULL)
	{
		return;
	}
	QueuePush(&q, root);//这里插入的是节点指针

	while (!QueueEmpty(&q))
	{
		BTNode* tem = QueueFront(&q);//这里的到的是节点指针
		QueuePop(&q);
		printf("%d ", tem->data);

		if(tem->left)
		{
			QueuePush(&q, tem->left);
		}

		if(tem->right)
		{
			QueuePush(&q,tem->right);
		}
	}
	printf("\n");
}

二叉树的节点个数

思路:从根节点出发,他的左子树的节点个数+它的右子树的节点个数+自己

int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

 

二叉树叶子节点个数 

思路:什么是叶子节点,他的左右孩子都是空,从头节点出发他的左子树的叶节点+右子树的叶节点

int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	if (root->left == NULL && root->right == NULL)
	{
		return  1;
	}
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

二叉树的高度 

思路:从根节点出发,看他的左子树的高度和右子树的高度哪个大就要哪个,大的+1

int BinaryTreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	int leftheight = BinaryTreeHeight(root->left);
	int rightheight = BinaryTreeHeight(root->right);

	return leftheight > rightheight ? leftheight + 1 : rightheight + 1;
}

自己画递归图理解啦

二叉树第k层节点个数

int BinaryTreeLevelkSize(BTNode* root,int k)
{
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	return BinaryTreeLevelkSize(root->left, k - 1) + BinaryTreeLevelkSize(root->right, k - 1);

}

 自己画递归图理解啦

二叉树中寻找元素

思路:从根节点出发,先找左子树,再找右子树找到就返回

BTNode* BinaryTreeFind(BTNode* root, int x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
	BTNode* tem1=BinaryTreeFind(root->left, x);
	if(tem1)
	return tem1;
	
	BTNode* tem2 = BinaryTreeFind(root->right, x);
	if (tem2)
	return tem2;

	return NULL;
}

错误写法:

1.

//错的
BTNode* BinaryTreeFind1(BTNode* root, int x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}

	return BinaryTreeFind1(root->left, x) || BinaryTreeFind1(root->right, x);
	/*不能这样返回,是真就返回1,假就是0,不能返回地址*/
}

2.

BTNode* BinaryTreeFind(BTNode* root, int x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
	BinaryTreeFind(root->left, x);//没有接收返回值
	BinaryTreeFind(root->right, x);
	
}

递归要小心返回值,返回值是返回给上一层函数 

二叉树的的销毁

思路:按照后序遍历销毁

void BinaryTreeDestory(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	BinaryTreeDestory(root->left);
	BinaryTreeDestory(root->right);
	free(root);
}

自己画递归图理解啦

总结:

  1. 二叉树是很多子树的集合,当你去写关于二叉树的代码时,可以先想象成简单的二叉树(两层的二叉树),从根节点出发,分为左右子树去想,写出思路,然后再添加子树进去,就会有递归了
  2. 递归一定要关注返回值,函数返回值是返回到原来的函数的,不是自己能返回到最外面的

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奇点 ♡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值