二叉树节点是否按引用传递?为何GetCount方法未修改原节点t2?
为什么修改GetCount方法的参数L不会影响原变量t2?
首先得明确一个关键概念:C#中引用类型的参数默认是按值传递的——这里传递的是「对象引用的副本」,而不是引用本身。这就是为什么你在GetCount里修改L的指向,t2却完全不受影响的原因。
具体拆解你的代码场景
先看你的GetCount方法:
static int GetCount(BinTreeNode<int> L) { int count = 0; while (L != null) { count++; L = L.GetRight(); // 这里只是修改参数L的指向 } return count; }
当你在Main里调用GetCount(t2)时,发生了这些事:
- t2是一个
BinTreeNode<int>类型的变量,它存储的是根节点对象在堆上的内存地址。 - 调用方法时,这个地址被复制了一份,传给了方法的参数L。此时L和t2指向同一个堆上的对象,但L是一个独立的变量。
- 循环里
L = L.GetRight()的操作,只是把L的指向改成了当前节点的右节点(或者最后改成null)——但这只改变了L这个副本的指向,完全不会影响t2原来存储的地址。
所以方法执行完后,t2依然指向原来的根节点,调用t2.GetInfo()自然还是输出1。
那什么时候会影响原变量?
如果你的方法修改的是L指向的对象的成员,而不是L的指向本身,那变化会反映到t2上。比如:
static void ModifyNodeInfo(BinTreeNode<int> L) { L.info = 100; // 修改对象的成员 }
调用ModifyNodeInfo(t2)后,t2的info成员就会变成100,因为L和t2指向同一个堆上的对象,修改对象的内容会被共享。
如何让修改L的指向影响t2?
如果确实需要在方法里修改参数的指向,同时影响原变量,你需要用ref关键字修饰参数,把参数改成按引用传递:
static int GetCount(ref BinTreeNode<int> L) { int count = 0; while (L != null) { count++; L = L.GetRight(); } return count; }
调用的时候也要加上ref:
GetCount(ref t2);
这时候传递的是t2变量本身的引用,修改L的指向就会直接改变t2的指向,调用结束后t2会变成null。
总结
- 二叉树节点(引用类型)默认是按值传递引用的副本,不是按引用传递变量本身。
- 修改参数的指向(比如
L = null或L = 另一个对象)只会影响参数变量,不会影响原变量。 - 只有用
ref/out修饰参数时,才是真正的按引用传递,此时修改参数的指向会同步到原变量。
内容的提问来源于stack exchange,提问作者Algo
相关产品推荐
相关产品推荐

