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

面试中的二叉树问题

2010-12-11 16:26 295 查看
二叉树中每个节点都有类似下面的定义

struct Node
{
int data;
Node *left, *right;
};

树的主要特征是树的每一个节点都可以看成是另外一棵树的根节点。因此任何对树的操作都可以分成三部分完成 1)对根节点的操作,2)对左子树的操作,3)对右子树的操作。根据这三种操作的先后次序,产生了三种不同的遍历方法:前序遍历(123),中序遍历(213),后续遍历(231)。因为树的定义本身就是递归定义的,所以大部分和二叉树有关的问题都可以用递归算法写出来。

Ex 1. 二叉树的最大深度

int depth(Node *root) //二叉树的深度等于1 + max{左子树的深度,右子树的深度}
{
if(root == 0)
return 0;
else
{
int depth1 = depth(root->left);
int depth2 = depth(root->right);
return depth1 > depth2 ? depth1 + 1 : depth2 + 1;
}
}

Ex 2. 二叉树中2个节点node1, node2的最小公共祖先节点

在后续遍历中,父节点总是在它的子节点之后遍历。所以node1, node2的最小公共祖先节点就是在遍历完它们之后遇见的第一个祖先节点。为了判断一个节点是否是他们的祖先节点,我们在遍历的时候保存一个计数器。1) 每一个节点的计数 = 左子节点的计数 + 右子节点的计数, 2)如果当前节点是node1或者node2,计数器+1。如果当前节点的计数等于2, 当前节点就是node1和node2的祖先节点。所以我们需要找到在后续遍历中第一个计数为2的节点。

//**ancestor保存找到的最小公共祖先节点,count保存root的计数
void commonAncestorHelper(Node *root, Node *node1, Node *node2, Node **ancestor, int* count)
{
if(root == 0 || *ancestor != 0) //如果已经找到祖先节点,直接返回
return;

int count1 = 0;
int count2 = 0;

//后续遍历
commonAncestorHelper(root->left, node1, node2, ancestor, &count1);
commonAncestorHelper(root->right, node1, node2, ancestor, &count2);

if(*ancestor != 0) //如果已经找到祖先节点,直接返回
return;

//计算当前节点的计数
*count = count1 + count2;
if(root == node1)
++(*count);

if(root == node2)
++(*count);

if(*count == 2)
{
*ancestor = root;
return;
}
}

Node* commonAncestor(Node *root, Node *node1, Node* node2)
{
if(root == 0)
return 0;
int count = 0;
Node *ancestor = 0;
commonAncestorHelper(root, node1, node2, &ancestor, &count);
return ancestor;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: