【问题标题】:Passing by reference vs Passing by value引用传递 vs 值传递
【发布时间】:2015-11-04 22:56:56
【问题描述】:

我目前正在学习破解编码面试,我相信我对指针的基本理解受到质疑。我目前正在寻找一种解决方案,为二叉树的每一级制作一个链表。解决方法如下:

void createLevelLinkedList(TreeNode root, ArrayList<LinkedList<TreeNode» lists, int level) {
    if (root == null) return; // base case
    LinkedList<TreeNode> list = null;
    if (lists.size() == level) { // Level not contained in list
        list = new LinkedList<TreeNode>();
        /* Levels are always traversed in order. So., if this is the
         * first time we've visited level i, we must have seen levels
         * 0 through i - 1. We can therefore safely add the level at
         * the end. */
        lists.add(list);
    } else {
        list = lists.get(level);
    }
    list.add(root);
    createLevelLinkedList(root.left, lists, level + 1);
    createLevelLinkedList(root.right, lists, level + 1);
}

ArrayList<LinkedList<TreeNode» createLevelLinkedList(TreeNode root) {
    ArrayList<LinkedList<TreeNode» lists = new ArrayList<LinkedList<TreeNode»();
    createLevelLinkedList(root, lists, 0);
    return lists;
}

这个解决方案让我非常困惑,因为在只有根参数(驱动程序函数)的 createLeveLinkedList 函数中,创建了一个新的链表列表。从java的角度来看,如果它是按值传递的,那么在调用 createLevelLinkedLists(root, lists, 0) 之后,据我了解,列表不应该改变。

如果是 C++,如果他们将列表对象的指针传递给函数,我就能理解。

有人可以澄清一下吗?

抱歉格式化,我仍然不确定它在stackoverflow上是如何工作的。

谢谢

【问题讨论】:

  • Java、C++、C、C#、Python、Haskell、BF、JS、MipsAsm?
  • 我实际上阅读了那篇文章,但我仍然需要澄清,据我了解,它声明列表不应该改变。我假设解决方案是用 Java 编写的。
  • Java 按值传递引用。 Java中作为值的“引用”与“按引用传递”的“引用”无关。 (这是一个不幸的命名冲突。)C++ 为“引用”引入了另一种含义。
  • passing an object (not a primitive) as a parameter into a function is passing the value of the reference, not the value itself? 是的。将一个全新的对象分配给函数内部的变量名不会在外部做任何事情,但更改传递的对象会。

标签: java c++ pointers reference


【解决方案1】:

Java 总是按值传递。然而,为复杂数据类型传递的值是引用的值,因此传递给 createLevelLinkedList(...)lists 引用与原始 lists 引用引用相同的对象。

只要不改变createLevelLinkedList(...)方法中引用的值,就会改变原来的对象。

正如保罗所说,这里全部写下来:

https://stackoverflow.com/a/40523/1619628

【讨论】:

  • 我认为这是有道理的。因此,如果我有一个二叉搜索树删除功能,如下所示: public Node BSTDelete(Node root, int value) { delete(root, int value);返回根;删除节点后,根会反映 BST 的根吗?
  • 我不确定你在 delete 中做了什么,但只要你不更改引用的值,所有更改都会发生在同一个对象上。
  • 如果删除是递归的并且root被设置为root.left/root.right,那么这些更改会被忽略吗?
  • 递归不会改变java传递参数的方式。它仍然按值传递引用。
  • 如果在delete里面,在向下遍历到被删除节点的过程中,发生了root=root.left或者root=root.right,然后再次调用delete(),会在BSTDelete中root还是点指向原始根,还是会指向在多次设置为 .left 或 .right 后最终成为的根?
猜你喜欢
  • 2014-09-14
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 2012-10-14
  • 2014-08-23
  • 2015-05-23
  • 1970-01-01
相关资源
最近更新 更多