指针之思考

 

116. 填充同一层的兄弟节点



 

给定一个二叉树

struct TreeLinkNode {
  TreeLinkNode *left;
  TreeLinkNode *right;
  TreeLinkNode *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

说明:

  • 你只能使用额外常数空间。
  • 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
  • 你可以假设它是一个完美二叉树(即所有叶子节点都在同一层,每个父节点都有两个子节点)。

示例:

给定完美二叉树,

     1
   /  \
  2    3
 / \  / \
4  5  6  7

调用你的函数后,该完美二叉树变为:

   1 -> NULL
   /  \
  2 -> 3 -> NULL
 / \  / \
4->5->6->7 -> NULL


原始二叉树根节点为TreeLinkNode* root。此时在内存中,有两个实体,一个是二叉树实体,一个是指针实体。实际只需要指针实体的指针按相应要求填充。我新建一个deque<TreeLinkNode* >容器,层次遍历二叉树,存放一个个TreeLinkNode*的指针,
此时产生第三个实体,指针实体2,如果我再新建一个临时变量TreeLinkNode* tmp,指向出队指针,此时产生第四个实体,临时变量指针3,我对临时变量的指针操作,并不能作用于root系列的指针。

----------------------------
更新,为了能对root系列指针产生操作,我们取root地址,将其入队,最终成功通过。
 1 /**
 2  * Definition for binary tree with next pointer.
 3  * struct TreeLinkNode {
 4  *  int val;
 5  *  TreeLinkNode *left, *right, *next;
 6  *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     void connect(TreeLinkNode *root) {
12         deque<TreeLinkNode** > Q;
13         if(!root)
14             return;
15         Q.push_back(&root);
16         while(!Q.empty())
17         {
18             int m=Q.size();
19             for(int i=0;i<m;i++)
20             {
21                 TreeLinkNode** tmp=Q.front();
22                 Q.pop_front();
23                 if(i<m-1)
24                     (*tmp)->next=*Q.front();
25                 else
26                     (*tmp)->next=NULL;
27                 if((*tmp)->left!=NULL)
28                     Q.push_back(&((*tmp)->left));
29                 if((*tmp)->right!=NULL)
30                     Q.push_back(&((*tmp)->right));
31             }
32             
33         }
34     }
35 };

 

 ---------------------------

更新,看到一个别的答案,跟我几乎完全一样,但是用的是一级指针,我将我的代码中二级指针全部换为一级指针,结果也通过了

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        deque<TreeLinkNode* > Q;
        if(!root)
            return;
        Q.push_back(root);
        while(!Q.empty())
        {
            int m=Q.size();
            for(int i=0;i<m;i++)
            {
                TreeLinkNode* tmp=Q.front();
                Q.pop_front();
                if(i<m-1)
                    tmp->next=Q.front();
                else
                    tmp->next=NULL;
                if(tmp->left!=NULL)
                    Q.push_back(tmp->left);
                if(tmp->right!=NULL)
                    Q.push_back(tmp->right);
            }
            
        }
    }
};

本来以为自己搞懂了,看来还是有问题,最后我梳理了一遍。

STL中deque的push_back操作调用了一个构造函数,复制了一个root,这时有三个实体, treenode t,  treenode *root,treenode *tmp,他们的关系是*root 等价于*tmp等价于t;

本来操作tmp,跟root没关系,但是为什么tmp->next改变后root->next也变了呢,因为上面那个等价关系,前面的改变相当于 (*tmp).next改变, 而(*root).next与(*tmp.next)是同一个,所以看起来没有动root,但是他们指向的内容是同一个,只要将指向的内容改变,就相当于改变了root。

再说回二级指针那里,二级指针是取root的地址,treenode **tmp,此时(*tmp)等价于root,操作就是相当于root操作,就改变了root。二级指针简单粗暴!

 

指针挺考验C++功力的,多级指针简单粗暴,一级指针优雅而晦涩难懂。

posted @ 2018-08-29 11:22  单纯的心  阅读(172)  评论(0)    收藏  举报