您的位置:首页 > 职场人生

一些关于树的面试题

2014-02-25 00:40 141 查看
之前讲了,也讲了其基本的操作。现在看看关于树的一些面试题

面试题:重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历序列{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:重建二叉树
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: