[英]Something I don't understand about a function in Binary Trees in C
Below is the code example for the insert code of a node into a tree. 下面是将节点插入到树中的代码示例。 The example is taken from http://cslibrary.stanford.edu/110/BinaryTrees.html The problem is this: I have a basic understanding of pointers and memory, and understand the whole thing but the insert node.
该示例来自http://cslibrary.stanford.edu/110/BinaryTrees.html问题是这样的:我对指针和内存有基本的了解,并且了解整个事情,但是插入节点。 here's the node struct:
这是节点结构:
struct node {
int data;
struct node* left;
struct node* right;
}
Now, in the page I provided, it says that this method of insertion is done to avoid the pass by reference. 现在,在我提供的页面中,它表示这种插入方法是为了避免通过引用传递。 so instead of calling
insert(struct node** nodeptr, int some data);
所以不要调用
insert(struct node** nodeptr, int some data);
it is called this way: nodeptr = insert(data int).
它以这种方式调用:
nodeptr = insert(data int).
so my question is. 所以我的问题是。 I understand the part of pointer assignment, that the pointer returned by the insert function is placed into nodeptr.
我理解指针赋值的一部分,insert函数返回的指针放在nodeptr中。 supposing that nodeptr is the root of the tree, how can it affect some node which will point to the new node.
假设nodeptr是树的根,它如何影响将指向新节点的某个节点。
struct node* insert(struct node* node, int data)
{
// 1. If the tree is empty, return a new, single node
if (node == NULL)
{
return(newNode(data));
}
else
{
// 2. Otherwise, recur down the tree
if (data <= node->data)
{
node->left = insert(node->left, data);
}
else
{
node->right = insert(node->right, data);
}
return(node); // return the (unchanged) node pointer
}
}
The left
and right
elements of a node of a binary tree can be NULL
if there are no further nodes connected to them. 如果没有连接到它们的其他节点,则二叉树的节点的
left
和right
元素可以是NULL
。 At such a node, if we traverse to a NULL
leaf then we create a new node with newNode(data)
. 在这样的节点上,如果我们遍历
NULL
叶子,那么我们用newNode(data)
创建一个新节点。
if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);
This code will call insert
on the node's left pointer if the data is smaller than the currently looked at node's data, or else it will call insert
on the node's right
pointer. 如果数据小于当前查看的节点数据,则此代码将在节点的左指针上调用
insert
,否则它将在节点的right
指针上调用insert
。 Eventually, when it has found the right place to insert, by recursively calling either of these insert
s in this if
statement, this will be a NULL node as there's no more nodes, it will create a new one and return
that, which will be appended to the previous node's left or right pointer. 最终,当它找到了正确的插入位置时,通过在这个
if
语句中递归调用这些insert
中的任何一个,这将是一个NULL节点,因为没有更多节点,它将创建一个新节点并return
它,这将是附加到上一个节点的左或右指针。 At this point it will go back up the recursion stack. 此时它将返回递归堆栈。
It might help to walk through the code for a few inserts. 可能有助于遍历代码以进行一些插入。 So, assuming we're calling
insert
from function foo
, our call tree would look something like this: 所以,假设我们从函数
foo
调用insert
,我们的调用树看起来像这样:
foo: root = NULL;
foo: root = insert(root, 5);
insert: if (node == NULL)
insert: return newnode(data); // newnode = 0xff864000
foo: root = 0xff864000
After this first call to data, our tree looks something like this: 在第一次调用数据之后,我们的树看起来像这样:
Address data left right ------- ---- ---- ----- 0xff864000 5 0x00000000 0x00000000
Now we make a second call to insert a new value: 现在我们再次调用以插入一个新值:
foo: root = insert(root, 3);
insert: if (node == NULL) // node == 0xff864000
insert: if (data <= node->data)
insert: node->left = insert(node->left, data);
Now we call insert
again; 现在我们再次调用
insert
; this time node
is the left child of the current node (which should be NULL): 这个时间
node
是当前节点的左子节点(应该为NULL):
insert(2): if (node == NULL) // node == 0x00000000
insert(2): return newnode(data); // newnode == 0xff86400c
insert: node->left = 0xff86400c;
insert: return node;
foo: root = 0xff864000
So the result of this second call to insert
is assigned to the left child of the current node, and our tree now looks something like this: 因此,第二次调用
insert
的结果被分配给当前节点的左子节点,我们的树现在看起来像这样:
Address data left right ------- ---- ---- ----- 0xff864000 5 0xff86400c 0x00000000 0xff86400c 3 0x00000000 0x00000000
Add another element: 添加另一个元素:
foo: root = insert(root, 2);
insert: if (node == NULL) // node = 0xff864000
insert: if (data <= node->data)
insert: node->left = insert(node->left, data);
insert(2): if (node == NULL) // node = 0xff86400c
insert(2): if (data <= node->data)
insert(2): node->left = insert(node->left, data);
insert(3): if (node == NULL)
insert(3): return newnode(data); // newnode = 0xff864018
insert(2): node->left = 0xff864018
insert(2): return node;
insert: node->left = 0xff86400c
insert: return node;
foo: root = 0xff8640000
And now our tree looks like 而现在我们的树看起来像
Address data left right ------- ---- ---- ----- 0xff864000 5 0xff86400c 0x00000000 0xff86400c 3 0xff864018 0x00000000 0xff864018 2 0x00000000 0x00000000
And finally: 最后:
foo: root = insert(root, 7);
insert: if (node == NULL) // node = 0xff864000
insert: if (data <= node->data)
insert: node->right = insert(node->right, data);
insert(2): if (node == NULL) // node = 0x0x00000000
insert(2): return newnode(data); // newnode = 0xff864024
insert: node->right = 0xff864024
insert: return node;
foo: root = 0xff8640000
Address data left right ------- ---- ---- ----- 0xff864000 5 0xff86400c 0xff864024 0xff86400c 3 0xff864018 0x00000000 0xff864018 2 0x00000000 0x00000000 0xff864024 7 0x00000000 0x00000000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.