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

1.把二元查找树转变成排序的双向链表(树)
 题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
     10
    /  \
   6    14
 / \    / \
4  8   12 16
转换成双向链表

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


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

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

即由               

     10
    /  \
   6    14
 / \    / \
4  8   12 16                   

先变成:

           10
      /         \
- 6 - 8   12 - 14 - 16

再变成:

- 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 
    }



你可能感兴趣的:(数据结构,算法,面试,微软)