面试经常考的常用的搜索方法有宽度优先搜索(BFS)和深度优先搜索(DFS):
(1) BFS算法:将从根结点出发,按从左到右的顺序先遍历第二层,再按从左到右的顺序遍历第三层……直到遍历完所有的结点或找到你想要的结点为止。这个算法的执行时间为O(n),不适合搜索尺寸很大的树。内存开销比较大,因为它在搜索每一层的同时需要把该层结点的子结点指针全都保存起来。
(2) DFS算法:将沿着树的某个分支一直向下搜索尽可能多的层,直到找到目标结点或到达这一分支的尽头;当搜索工作到达这一分支尽头时,它将从距离最近且有子结点尚未被搜索过的祖先处开始继续搜索。与BFS相比,DFS的内存开销要小得多,因为它不需要把各层结点的子指针保存。此外,DFS不会特意把某一层留到最后才去搜索(BFS树的最底层将最后搜索)
面试题目1:对二元搜索树进行左遍历并输出各结点的值。函数的调用接口不变,但不允许使用递归方法。
算法如下:
void PreorderTraversal(node *root)
{
element *theStack;
void *data;
node *curNode;
CreateStack(&theStack);
Push(&theStack,root);
while(Pop(&theStack,&data))
{
curNode=(node*)data;
if(curNode)
{
printf(“%d\n”,curNode->value);
Push(&theStack,curNode->right);
Push(&theStack,curNode->left);
}
}
DeleteStack(&theStack);
}
面试题目2:已知二元搜索树上两个结点的值,请找出它们的最低公共祖先。你可以假设两个值肯定存在,这个函数的调用接口如下所示:
intFindLowestCommonAncestor(node *root, int value1,int value2)
分析:根结点是一切结点的祖先,从根结点出发可以到达任何一个结点。因此,从根结点出发,沿着两个给定结点的公共祖先前进。当这两个结点的值同时小于当前结点的值时,沿左指针前进;当这两个结点的值同时大于当前结点值时,沿右指针前进;当第一次遇到当前结点的值介于两个给定的结点值之间的情况时,这个当前结点就是要找的最低公共祖先了。
算法如下:
intFindLowestCommonAncestor(node *root, int value1,int value2)
{
node *curNode=root;
while(1)
{
if(curNode->value>value1&&curNode->value>value2)
curNode=curNode->left;
else if(curNode->value<value1&&curNode->value<value2)
curNode=curNode->right;
else
return curNode->value;
}
}