我正在研究《Programming Interviews Exposed》一书中的以下算法来展平树状链表系统:
void flattenList( Node *head, Node **tail)
Node *curNode = head;
while( curNode ){
/* The current node has a child */
if( curNode->child ){
append( curNode->child, tail );
}
curNode = curNode->next;
}
}
/* Appends the child list to the end of the tail and updates
* the tail.
*/
void append( Node *child, Node **tail ){
Node *curNode;
/* Append the child child list to the end */
(*tail)->next = child;
child->prev = *tail;
/*Find the new tail, which is the end of the child child
*list.
*/
for( curNode = child; curNode->next;
curNode = curNode->next )
; /* Body intentionally empty */
/* Update the tail pointer now that curNode is the new
* tail.
*/
*tail = curNode;
}
据我了解,我们将 **tail
而不是 *tail
传递到 append
函数中,以确保对 的更改*tail
仍然存在,但我不明白的是为什么我们不对 child 做同样的事情(这意味着为什么我们不传递 **child
而不是 * child
)?
最佳答案
C 使用“按值调用”参数传递语义。这意味着,如果您调用像 f(x)
这样的函数,则只有 x
的值会传递给该函数,而不是变量 x
本身。当您为函数内部的参数赋值时,用于调用函数的 x
不会改变。
如果您希望能够更改变量本身,则必须像此调用 f(&x)
中那样传递地址,然后再对 *x
进行赋值> 在函数内部,您更改了变量 x
。
flattenList
按原样声明,因为 head
是按值传递的(它不会改变),但 tail
是与其地址一起传递的因为函数必须改变它。
这类似于append
函数。第一个参数不会改变,而第二个参数必须在函数内部改变。
关于c - 链表展平算法指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14057869/