(1)实现由先序、中序序列构造二叉树的算法(2)实现由后序、中序序列构造二叉树的算法 (3)定义最大堆,封装堆的初始化、插入和删除元素的操作


题目
(1)实现由后序、中序序列构造二叉树的算法
(2)实现由先序、中序序列构造二叉树的算法
(3)定义最大堆,封装堆的初始化、插入和删除元素的操作

实现由后序、中序序列构造二叉树的算法

后序遍历:左右根
中序遍历:左根右
后序遍历的最后一个元素为root,然后在中序中找到root,中序中root左边为左子树,右边为右子树,从而确定了左右子树的长度。然后在后序遍历中找到相应的左子树和右子树,进行递归的遍历下去。
例子:如果一颗二叉树为{1,2,3,4,5,6,7},则中序遍历为{4,2,5,1,6,3,7},后序遍历为{4,5,2,6,7,3,1},我们可以反推回去。由于后序遍历的最后一个节点就是树的根。也就是root=1,然后我们在中序遍历中搜索1,可以看到中序遍历的第四个数是1,也就是root。根据中序遍历的定义,1左边的数{4,2,5}就是左子树的中序遍历,1右边的数{6,3,7}就是右子树的中序遍历。而对于后序遍历来讲,一定是先后序遍历完左子树,再后序遍历完右子树,最后遍历根。于是可以推出:{4,5,2}就是左子树的后序遍历,{6,3,7}就是右子树的后序遍历。而我们已经知道{4,2,5}就是左子树的中序遍历,{6,3,7}就是右子树的中序遍历。再进行递归就可以解决问题了。

template<class T>
BinaryTreeNode<T>* BinaryTree<T>::Build1(T* pos, int s1, int e1, T* in, int s2, int e2)
{
	if (s1 > e1)
		return NULL;
	T rootdata = pos[e1];
	BinaryTreeNode<T>* root = new BinaryTreeNode<T>(rootdata);
	int j = 0;
	for (j = s2; j < e2; j++)
	{
		if (rootdata == in[j])
			break;
	}
	int leftlen = j - s2;
	int rightlen = e2 - j;
	if (leftlen > 0)
		root->LeftChild = Build1(pos, s1 , s1 + leftlen - 1, in, s2, j - 1);
	if (rightlen > 0)
		root->RightChild = Build1(pos, s1 + leftlen , e1 - 1, in, j + 1, e2);
	return root;
}

实现由先序、中序序列构造二叉树的算法

先序遍历:根左右
中序遍历:左右根

template<class T>
BinaryTreeNode<T>* BinaryTree<T>::Build(T* pre, int s1, int e1, T* in, int s2, int e2)
{
	if (s1 > e1)
		return NULL;
	T data = pre[s1];
	BinaryTreeNode<T>* root = new BinaryTreeNode<T>(data);
	int leftlen = 0, rightlen = 0;
	int tag = s2;  //一定注意开始给tag赋值,不执行for循环时 tag = s2
	for (int i = s2; i < e2; i++)
	{
		if (data == in[i])
		{
			tag = i;
			break;
		}
	}
	leftlen = tag - s2;
	rightlen = e2 - tag;
	if (leftlen > 0)
		root->LeftChild = Build(pre, s1 + 1, s1 + leftlen , in, s2, tag - 1);
	if (rightlen > 0)
		root->RightChild = Build(pre, s1 + leftlen + 1, e1, in, tag + 1, e2);
	return root;
}

定义最大堆,封装堆的初始化、插入和删除元素的操作

堆的定义:堆是一种经过排序的完全二叉树或满二叉树,
最大堆:就是不不断变得进行树元素替换,最终是树呈现上面数值最大;
最小堆:就是不不断变得进行树元素替换,最终是树呈现上面数值最小;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 先序遍历的第一个节点一定是根节点,根据这个特点,我们可以在中序遍历中找到根节点的位置。根据中序遍历的性质,根节点的左边是左子树的中序遍历,右边是右子树的中序遍历。同样地,先序遍历的第二个节点一定是左子树的根节点,根据这个特点,我们可以在先序遍历中找到左子树的根节点。右子树的根节点也可以通过先序遍历找到。 有了这些信息,我们可以递归地构造二叉树。具体地,我们先根据先序遍历的第一个节点创建根节点,然后在中序遍历中找到根节点的位置,根据这个位置将中序遍历分成左右两个部分。左边部分是左子树的中序遍历,右边部分是右子树的中序遍历。同样地,在先序遍历中,根据左子树的根节点和右子树的根节点,将先序遍历分成左右两个部分。左边部分是左子树的先序遍历,右边部分是右子树的先序遍历。然后递归地构造左子树和右子树即可。 具体实现可以参考下面的代码: ``` class TreeNode: def __init__(self, val=, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(preorder, inorder): if not preorder or not inorder: return None root_val = preorder[] root = TreeNode(root_val) root_index = inorder.index(root_val) left_inorder = inorder[:root_index] right_inorder = inorder[root_index+1:] left_preorder = preorder[1:1+len(left_inorder)] right_preorder = preorder[1+len(left_inorder):] root.left = buildTree(left_preorder, left_inorder) root.right = buildTree(right_preorder, right_inorder) return root ``` 其中,preorder和inorder分别表示先序遍历和中序遍历的列表。函数返回构造出的二叉树的根节点。 ### 回答2: 1. 算法说明: 由先序序列中序序列可以唯一确定一棵二叉树。因此我们可以通过先序序列中序序列构造出对应的二叉树。具体的实现步骤如下: 2. 算法实现: Step 1:用先序序列的第一个元素建立根节点。 Step 2:在中序序列中找到根节点的位置,以此将中序序列分为左右两个子序列。 Step 3:在先序序列中找到对应中序序列中左子序列的最后一个元素,建立为根节点的左子节点。 Step 4:通过递归,在左子树的先序序列中序序列中重复步骤1、2、3,构建出左子树。 Step 5:在先序序列中序序列中分别找到对应右子序列的第一个元素,建立为根节点的右子节点。 Step 6:通过递归,在右子树的先序序列中序序列中重复步骤1、2、3、5、6,构建出右子树。 Step 7:返回根节点作为结果。 3. 复杂度分析 该算法的时间复杂度为O(n),其中n为二叉树的节点数。因为在每次递归中,我们都需要在中序序列中寻找根节点位置,这需要O(n)的时间复杂度。而每个节点恰好只被访问一次,因此总的时间复杂度为O(n)。 同时,该算法的空间复杂度也为O(n),因为我们需要开辟O(n)的空间存储整棵二叉树。 ### 回答3: 由先序中序序列构造二叉树是一道经典的算法问题。这个问题的实现需要对二叉树结构、二叉树遍历方式、递归思想等知识点有深入的了解。 先序序列是指先遍历根节点,再遍历左子树,最后遍历右子树。中序序列是指先遍历左子树,再遍历根节点,最后遍历右子树。因此,根据先序中序序列,我们可以确定二叉树的根节点和左右子树的先序中序序列。 具体的实现步骤如下: 1. 从先序序列中取出第一个元素作为根节点。 2. 在中序序列中找到根节点的位置,该位置左边的元素构成二叉树的左子树中序序列,右边的元素构成二叉树的右子树中序序列。 3. 在先序序列中,从第二个元素开始,取出与左子树中序序列相同数量的元素,这些元素构成二叉树的左子树先序序列,剩下的元素构成二叉树的右子树先序序列。 4. 对左子树进行递归构造,得到左子树的根节点,并将其设为根节点的左子节点。 5. 对右子树进行递归构造,得到右子树的根节点,并将其设为根节点的右子节点。 6. 返回根节点。 需要注意的是,如果先序序列中序序列为空,那么返回空节点。如果先序序列中序序列的长度不相等,那么抛出错误信息。 在实现过程中,需要进行递归操作,因此需要清楚递归的终止条件、递归的参数和递归的返回值。同时,需要对二叉树节点的定义有清晰的认识,包括节点的值、左节点和右节点等属性。 实现先序中序序列构造二叉树算法,不仅考察了对二叉树的理解,还考察了递归思想和代码能力。如果能够熟练地掌握这个算法,对于解决其他与二叉树相关的问题也会有帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值