您的位置:首页 > 理论基础 > 数据结构算法

微软公司等数据结构+算法面试100题-第1题

2012-11-21 15:20 267 查看
1.把二元查找树转变成排序的双向链表(树)

题目:

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

要求不能创建任何新的结点,只调整指针的指向。

10

/ \

6 14

/ \ / \

4 8 12 16

转换成双向链表

4=6=8=10=12=14=16。

看到这题 ,想到一个动画 ,最后要得到的双向链表无非是要将这棵二叉树串成有序的一串。从二维变成一维。

相像一个从树的叶结点一层层向上一层的结点中插入的过程。

即由

10

/ \

6 14

/ \ / \

4 8 12 16

先变成:

10

/ \

4 - 6 - 8
12 - 14 - 16

再变成:

4 - 6 - 8 -
10 - 12 - 14 - 16

这就是最后要的结果了。

用递归,从最下面一层开始向上一层插入。要做的就是修改指针的指向。

把4跟8分别插入到6的前跟后的时候,6的左指针不用修改,右指针也不用修改。只需要将4的右指针指向6, 再将8的左指针指向6即可。

再将4-6-8看作整体,插入到它们的上一层也就是10。这时候 ,10的左指针指向6,而它应该指向8才对,所以这一步插入的时候要先将10的左指针右移直到找到4-6-8中最右边的结点为止,将10的左指针指向它(这个例子中是8)即可。

对于12-14-16的组合同理,将10的右指针左移,直到找到最左边的结点为12,指向它。

最后得到的输出就是想要的结果了。

最核心的转换代码如下。

void insert_pro(tnode* root,tnode* newa){
//每次将左孩子对父节点做前插的时候,考虑到待插入的是一个已经链好的链表,需要找到其尾结点
while(newa->getrigh())
newa=newa->getrigh();
newa->setright(root);
root->setleft(newa);
}
void insert_next(tnode* root,tnode* newa){
while(newa->getleft())
newa=newa->getleft();
root->setright(newa);
newa->setleft(root);
}
void bitree2bilist(tnode* root){
tnode* tp;
if(tp=root->getleft()){
bitree2bilist(tp);
insert_pro(root,tp);// insert the node to root's left
}
if(tp=root->getrigh()){
bitree2bilist(tp);
insert_next(root,tp);// insert the node to root's right
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: