Algorithm 使用恒定的额外空间连接同一级别的节点
目标:编写一个函数来连接二叉树中同一级别的所有相邻节点。给定的二叉树节点的结构如下所示Algorithm 使用恒定的额外空间连接同一级别的节点,algorithm,tree,time-complexity,Algorithm,Tree,Time Complexity,目标:编写一个函数来连接二叉树中同一级别的所有相邻节点。给定的二叉树节点的结构如下所示 struct node{ int data; struct node* left; struct node* right; struct node* nextRight; } 最初,所有nextRight指针都指向垃圾值。函数应该为每个节点将这些指针设置为指向下一个右侧 解决方案: void connectRecur(struct node* p); struct node *getNe
struct node{
int data;
struct node* left;
struct node* right;
struct node* nextRight;
}
最初,所有nextRight指针都指向垃圾值。函数应该为每个节点将这些指针设置为指向下一个右侧
解决方案:
void connectRecur(struct node* p);
struct node *getNextRight(struct node *p);
// Sets the nextRight of root and calls connectRecur() for other nodes
void connect (struct node *p)
{
// Set the nextRight for root
p->nextRight = NULL;
// Set the next right for rest of the nodes (other than root)
connectRecur(p);
}
/* Set next right of all descendents of p. This function makes sure that
nextRight of nodes ar level i is set before level i+1 nodes. */
void connectRecur(struct node* p)
{
// Base case
if (!p)
return;
/* Before setting nextRight of left and right children, set nextRight
of children of other nodes at same level (because we can access
children of other nodes using p's nextRight only) */
if (p->nextRight != NULL)
connectRecur(p->nextRight);
/* Set the nextRight pointer for p's left child */
if (p->left)
{
if (p->right)
{
p->left->nextRight = p->right;
p->right->nextRight = getNextRight(p);
}
else
p->left->nextRight = getNextRight(p);
/* Recursively call for next level nodes. Note that we call only
for left child. The call for left child will call for right child */
connectRecur(p->left);
}
/* If left child is NULL then first node of next level will either be
p->right or getNextRight(p) */
else if (p->right)
{
p->right->nextRight = getNextRight(p);
connectRecur(p->right);
}
else
connectRecur(getNextRight(p));
}
/* This function returns the leftmost child of nodes at the same level as p.
This function is used to getNExt right of p's right child
If right child of p is NULL then this can also be used for the left child */
struct node *getNextRight(struct node *p)
{
struct node *temp = p->nextRight;
/* Traverse nodes at p's level and find and return
the first node's first child */
while(temp != NULL)
{
if(temp->left != NULL)
return temp->left;
if(temp->right != NULL)
return temp->right;
temp = temp->nextRight;
}
// If all the nodes at p's level are leaf nodes then return NULL
return NULL;
}
此解决方案的时间复杂度是多少?在我看来,您是从根节点开始按级别连接节点 在任何级别,由于父级已经连接,您只需通过父级联系到下一个分支。因此,您最多只能访问每个节点一次(或通过子节点访问两次) 因此,对我来说,时间复杂度的顺序似乎是O(n),其中n是树中元素的总数。它是O(n^2),因为getNextRight 最容易看到的是考虑你有一个完整的二叉树。叶子的数量是O(n/2)so O(n)。您可以为每个叶调用getNextRight 第一个getNextRight将用于右边的最后一片叶子。这不需要通过while循环 接下来,为右边的下一个到最后一个叶调用getNextRight。这需要1次通过while循环 对于下一个叶,您将通过while循环获得2次。等等你得到O(1+2+3+…+n/2),也就是O(n^2)
而且空间复杂度并不是恒定不变的。如果树由于递归而平衡,则为O(logn)。您可能有一个log n大小的堆栈。如果树不平衡,它将是最糟糕的。我在这里用水平顺序遍历回答了一个类似的问题。空间和时间的复杂性是O(n)你能解释一下你是如何得出这个结论的吗?请看我的答案以了解解释。虽然注释很好,但这是相当多的代码。您可能想学习如何编写和/或编写足够详细的高级描述。请批准正确答案,因为有两个不同的答案。我在上提供了一个类似问题的答案