【C语言】二叉树递归思想的简单运用

1.二叉树的销毁 (后序)

思路:

有点三过家门而不入 的感觉。

代码:

// 二叉树销毁
void TreeDestroy(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	TreeDestroy(root->left);
	TreeDestroy(root->right);
	free(root);
	//root = NULL
}

         root用不用置空要考虑 形参的改变不会影响实参

2.二叉树节点个数

思路:

        分治思想

代码:

int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

3.二叉树叶子节点个数

思路:

 和找节点个数思路相似,但是些限定条件,要根左子树右子树都为空才能返回1。后边也是左子树和右子树相加返回根

代码:

//叶子结点个数
int TreeLeafSize(BTNode* root)
{
    //空返回 0
	if (root == NULL)
	{
		return 0;
	}
    
    //叶子返回 1
	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}
    
    //左子树+右子树
	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

4.二叉树第k层节点个数

思路:

代码:

int TreeKLevel(BTNode* root, int k)
{
	assert(k > 0);

	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}

	return TreeKLevel(root->left, k - 1)
		 + TreeKLevel(root->right, k - 1);

}

5.二叉树中查找值为x的节点 (前序)

思路:

代码:

BTNode* TreeFind(BTNode* root, int x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->val = x)
	{
		return root->val;
	}

	//先定义一个返回值
	BTNode* ret = NULL;
	//开始递归左子树和右子树
	ret = TreeFind(root->left, x);
	if (ret)
	{
		return ret;
	}
	
	ret = TreeFind(root->right, x);
	if (ret)
	{
		return ret;
	}

	return NULL;
}

6.二叉树的前序遍历(中序和后序遍历思想是一样的)

思路:

代码:

//前序遍历
void PrevOder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	printf("%d ", root->val);
	PrevOder(root->left);
	PrevOder(root->right);
}
//中序和后序就是调换一下printf的位置

7.层序遍历

思路:

代码:

//层序遍历
void LevelOrder(BTNode* root)
{
	Que q;
	QueueInit(&q);

//根不为空把根入进去
	if (root)
	{
		QueuePush(&q, root);
	}

	while (!QueueEmpty(&q))
	{
        //取队头节点,先进先出
		BTNode* front = QueueFront(&q);
		printf("%d", front->val);
        
        //把左右孩子入进去再出来,空不进去。根出去的时候左右子树也要入队
		if (front->left)
		{
			QueuePush(&q, front->left);
		}

		if (front->right)
		{
			QueuePush(&q, front->right);
		}

		QueuePop(&q);
	}

	printf("\n");
	QueueDestroy(&q);
}

ps:会用到列表的知识,因为不是重点所以代码没写 。

有些注意事项:.h会被展开,所以放在下面,它会向上找。用树节点的指针

8.判断二叉树是不是完全二叉树

思路:

 

代码:

//判断二叉树是否是完全二叉树
int  TreeComplete(BTNode* root)
{
	Que q;
	QueueInit(&q);

	if (root)
	{
		QueuePush(&q, root);
	}

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		if (front == NULL)
		{
			break;
		}

		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
		QueuePop(&q);
	}

	//已经遇到空节点,如果队列中后面的节点还有非空,就不是完全二叉树
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		if (front != NULL)
		{
			QueueDestroy(&q);
			return false;
		}
		
	}

	QueueDestroy(&q);
	return true;
}

9.通过前序遍历的二叉树的数组"ABD##E#H##CF##G##"构建二叉树

思路:

代码:

BTNode* CreateTree(BTDataType* a, int n, int* pi)
{
	if (a[*pi] == '#')
	{
		(*pi)++;
		return NULL;
	}

	BTNode* root = (BTNode*)malloc(sizeof(BTNode)*n);
	root->val = a[*pi];
	(*pi)++;

	root->left = CreateTree(a, n, pi);
	root->right = CreateTree(a, n, pi);

	return root;
}

这段代码主要作用是在于理解。

总结:

理解困难就画递归展开图理解,但是要慢慢的能在树上画图理解。如果是理解了写不出来就多练多思考。多花点时间去消化,找一些题目做做,后边的学习都是以前边的为基础。

《杂谈随想录》:

之前有人告诉我60分更重要,硅谷有句名言叫move fast and break things,意思是说要快速的行动,即便事情会被搞砸。每个人每天都有很多事情要执行,但是执行起来很慢,因为感觉自己所具备的条件不够完美或者计划还不够周全,就会担心失败担心做不到100分,所以迟迟都不会行动。我之前每次做一件事情之前都喜欢暗示自己要尽可能做到完美,这样最大的影响就是给自己不必要的压力,让自己迟迟不能开始行动,其实100分根本不重要,60分才重要,因为60分至少让你有了开始行动的动力,做一件100分事情的精力,可以帮你完成很多件60分的事情。
之前我不是很理解,现在想他当时想表达给我的意思是,不要还没做就想着一定要做到100分,而是冒着即使60分也要开始的心态,在开始以后再不断调试的做到更好。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

No more cages

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

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

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

打赏作者

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

抵扣说明:

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

余额充值