二叉树——进阶(递归创建,非递归,广度优先,翻转,深度,对称)

二叉树的递归创建

1,二叉树是一种结构相对固定的数据,分为根,左节点,右节点,把一颗大树拆分开每部分都是如此,这就有了递归创建的条件。

2,采用递归,第一时间需要思考递归的三步骤。

  • 基本情况(Base Case): 定义递归算法终止的条件。在递归的过程中,需要确定一个或多个基本情况,当满足这些情况时,递归将停止并返回结果,避免进入无限递归的循环。

  • 递归调用(Recursive Call): 在算法的定义中,通过调用自身来解决问题的步骤。递归调用必须逐渐朝着基本情况靠近,以确保算法能够最终终止。

  • 向基本情况靠近(Making Progress Towards Base Case): 确保递归调用的每一步都朝着基本情况的方向迈进。这意味着在每次递归调用中,问题的规模都会减小,最终达到一个基本情况。

3,这里采用先序创建二叉树,思考递归的终止条件,显而易见,就是遇见空节点时,数据采用整数,每层需要自己输入,还需要返回值,返回根节点。

代码实现

typedef struct Binary_Tree
{
   
   
	DataType val;

	struct Binary_Tree* left;
	struct Binary_Tree* right;

	struct Binary_Tree() {
   
   }
	struct Binary_Tree(int v)
	{
   
   
		val = v;
		left = NULL;
		right = NULL;
	}
}TreeNode;

//递归先序创建树
TreeNode* create_Tree()
{
   
   
	int x;
	cin >> x;

	if (x == -1)  //终止条件
	{
   
   
		return NULL;
	}
	
	//数据处理,单层的逻辑执行
	TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
	if (root == NULL)
		exit(-1);

	root->val = x;
	
	//递归创建左右树
	root->left = create_Tree();
	root->right = create_Tree();
	
	//返回结果
	return root;
}

非递归前中后序遍历

1, 非递归遍历树,需要用到数据结构——栈来模拟递归时的过程,并且更加复杂一些,需要判断循环终止条件,循环中对树节点的处理,需要多种数据辅助。

非递归前序遍历

非递归先序遍历二叉树的要点通常包括以下几个步骤

1,使用栈数据结构: 在非递归算法中,通常会使用栈来模拟递归调用的过程。栈用于存储待访问的节点,以便稍后访问它们的子节点。

2,遍历顺序: 先序遍历的顺序是先访问根节点,然后递归地访问左子树和右子树。因此,在非递归算法中,首先将根节点入栈。

3,迭代过程:

  • 弹出栈顶元素,访问该节点。
  • 将该节点的右子节点(如果存在)入栈,然后将左子节点(如果存在)入栈。注意要先将右子节点入栈,再将左子节点入栈,以保证左子节点在栈中靠近栈顶,右子节点在栈中靠近栈底,这样才能保证先访问左子树。
  • 重复以上步骤,直到栈为空。

4,循环条件: 在循环中,应该判断栈是否为空,以确定是否继续遍历。当栈为空时,表示已经遍历完整棵树。

代码实现

//非递归先序遍历
void non_recursion_PreorderTree(TreeNode* root)
{
   
   
	if (root == NULL)
	{
   
   
		return;
	}

	//栈结构
	stack<TreeNode*> Tree;

	Tree.push(root);

	while (!Tree.empty())
	{
   
   
		TreeNode* tem = Tree.top();

		cout << tem->val << " ";
		Tree.pop();

		if (tem->right != NULL)
			Tree.push(tem->right);

		if (tem->left != NULL)
			Tree.push(tem->left);
	}
}

非递归中序遍历

非递归中序遍历二叉树的要点包括以下几个步骤

1,使用栈数据结构: 与先序遍历类似,在非递归算法中也会使用栈来模拟递归调用的过程。栈用于存储待访问的节点,以便稍后访问它们的子节点。

2,遍历顺序: 中序遍历的顺序是先访问左子树,然后访问根节点,最后访问右子树。因此,在非递归算法中,首先将根节点入栈,并将当前节点指向根节点的左子节点。

3,迭代过程:

  • 将当前节点的所有左子节点入栈,直到没有左子节点为止。
  • 弹出栈顶元素,访问该节点。
  • 将当前节点指向该节点的右子节点。
  • 重复以上步骤,直到栈为空且当前节点为空。

4,循环条件: 在循环中,应该判断栈是否为空或当前节点是否为空,以确定是否继续遍历。当栈为空且当前节点为空时,表示已经遍历完整棵树。

代码实现

//非递归中序遍历
void non_recursion_MidorderTree(TreeNode* root)
{
   
   
	if (root == NULL)
	{
   
   
		return;
	}

	stack<TreeNode*> Tree;
	TreeNode* cur = root;
	Tree.push(cur);
	while (!Tree.empty(
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值