数据结构上机题-构造二叉树、定义最大堆
题目
(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;
}
定义最大堆,封装堆的初始化、插入和删除元素的操作
堆的定义:堆是一种经过排序的完全二叉树或满二叉树,
最大堆:就是不不断变得进行树元素替换,最终是树呈现上面数值最大;
最小堆:就是不不断变得进行树元素替换,最终是树呈现上面数值最小;