完全二叉树的点插入

完全二叉树的点插入
From: http://hi.baidu.com/gmchen/blog/item/780c8202aab75b0b4afb517d.html
分享一道曾经的谷歌面试题,觉得特别经典。

        题目:对于一颗完全二叉树,插入一个新的节点。
        struct node
        {
          int data;
            struct node * left;
            struct node * right;
        };
        声明: insert(struct node * tree, struct node new_node);

       完全二叉树的点插入_第1张图片   完全二叉树的点插入_第2张图片
        由于是一颗完全二叉树,所以插入的顺序可以参考图示,插入了节点4,之后应该是节点5。

        拿到题目第一反应就是按层便利,用bfs的就可以搞定,效率在O(n),实现起来也简单,用一个队列就可以完成,这里不多说了。
        当时考官并不满意,于是就有了第二种解法(提示下),试想下如何比O(n)更快呢? 那么就往logn上去考虑了,很自然的想到了二分查找,对于不同的数组而言,二分查找就是找中间的那个点。
        但本题比较特别,因为是完全二叉树,那么插入的点只能在最下一层。于是我们可以去找最下一层的中间点,找到根的左子树的最右下的节点,如果这个点存在,那么说明,最下一层的左边已经填满,递归右子树,否则递归左子树。
   
       完全二叉树的点插入_第3张图片 完全二叉树的点插入_第4张图片


        还是用图例来看会比较清楚(黄色的点代表当前递归的根节点,红色的点代表左子树的最右节点),这里是要插入节点7,当递归到5的右子树时,可以插入。这个算法的复杂度大概在logn到n之间,具体忘记了,有兴趣可以推算下。
        总结:其实这个题目的解答太巧了,要在面试中一步到位基本不可能,但是如果可以在面试官的提示下摸到思路,那么已经达到要求了。再就是如果面到这类题目,不妨先把最简单的bfs方法答上,然后可以在提示下不断改进。

你可能感兴趣的:(完全二叉树的点插入)