之前讲了树,也讲了其基本的操作。现在看看关于树的一些面试题
面试题:重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出图2.6所示的二叉树并输出它的头结点。二叉树结点的定义如下:
struct Binary Tree Node
{
int m_nValue;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
这题就是间接考查遍历了,所以我们一定要把3种遍历的6种实现方法都了如指掌。
根据定义,先序遍历首先遍历的是根结点,所以先序序列中,第一个结点一定是二叉树的根结点。但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边。所以,根结点在中序序列中必然将中序序列分割成两个子序列,前一个子序列是根结点的左子树的中序序列,而后一个子序列是根结点的右子树的中序序列。如此类推。
思路出来的,接下来要怎样写呢?不如先看看二叉树是怎样创建的吧。
void createBiTree(BiTree &T){
//按先序次序输入二叉树中结点的值('#'表示空格),构造二叉链表表示的二叉树T。
TElemType ch;
cin>>ch;
if(ch=='#') // 空
T=NULL;
else{
T=new BiTNode;
if(!T)
exit(1);
T->data=ch; // 生成根结点
createBiTree(T->lchild); // 构造左子树
createBiTree(T->rchild); // 构造右子树
}
typedef struct _treenode
{
char data;
struct _treenode *left;
struct _treenode *right;
} treenode;
/*
函数名称:pre_mid_tree
函数功能:给定二叉树的先序与中序序列,建立二叉树。
输入参数: treenode *tree:二叉树的结点tree
char pre[]:存储了二叉树的先序序列的字符数组
char mid[]:存储了二叉树的中序序列的字符数组
int lp, int rp:二叉树的先序序列在数组pre中的左右边界
int lm, int rm:二叉树的中序序列在数组mid中的左右边界
*/
treenode * pre_mid_tree(treenode *tree, char pre[], char mid[],
int lp, int rp, int lm, int rm)
{
int pos;
int len;
tree = (treenode *)malloc(sizeof(treenode));
tree->data = pre[lp];
tree->left = tree->right = NULL;
pos = lm;
while(mid[pos] != pre[lp])
pos++;
len = pos - lm;
if(pos > lm)
tree->left = pre_mid_tree(tree->left, pre, mid,
lp+1, lp+len, lm, pos-1);
if(pos < rm)
tree->right = pre_mid_tree(tree->right, pre, mid,
lp+len+1, rp, pos+1, rm);
return tree;
}
同样的道理,由二叉树的后序序列和中序序列也可唯一地确定一棵二叉树。因为,依据后序遍历和中序遍历的定义,后序序列的最后一个结点,就如同先序序列的第一个结点一样,可将中序序列分成两个子序列,分别为这个结点的左子树的中序序列和右子树的中序序列,再拿出后序序列的倒数第二个结点,并继续分割中序序列,如此递归下去,当倒着取取尽后序序列中的结点时,便可以得到一棵二叉树。
/*
函数名称:post_mid_tree
函数功能:给定二叉树的后序与中序序列,建立二叉树。
输入参数: treenode *tree:二叉树的结点tree
char post[]:存储了二叉树的后序序列的字符数组
char mid[]:存储了二叉树的中序序列的字符数组
int lp, int rp:二叉树的后序序列在数组post中的左右边界
int lm, int rm:二叉树的中序序列在数组mid中的左右边界
*/
treenode * post_mid_tree(treenode *tree, char post[], char mid[],
int lp, int rp, int lm, int rm)
{
int pos;
int len;
tree = (treenode *)malloc(sizeof(treenode));
tree->data = post[rp];
tree->left = tree->right = NULL;
pos = lm;
while(mid[pos] != post[rp])
pos++;
len = pos - lm;
if(pos > lm)
tree->left = post_mid_tree(tree->left, post, mid,
lp, lp+len-1, lm, pos-1);
if(pos < rm)
tree->right = post_mid_tree(tree->right, post, mid,
lp+len, rp-1, pos+1, rm);
return tree;
}
未完。。
参考:
http://hi.baidu.com/passerryan/item/eec97696e1e540bc82d29524
剑指offer面试题6:重建二叉树