指针之思考
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++功力的,多级指针简单粗暴,一级指针优雅而晦涩难懂。

浙公网安备 33010602011771号