
重新实现了简单的 LinkedList,关键逻辑如下: public void reverse()中调用了 first.reverse(),而 reverse 中并没有对变量 last 做任何操作啊,只是对 first 做了修改,最后调试发现最后一次执行完 this.next = newNext;这一行(53 行)的时候,last 的值就会改变。我看来 last 作为一个独立的变量怎么不应该被 this 影响到啊,想了一下午也没搞明白,求教,感谢送上。
下面是完整代码,问题只和两个 reverse 方法有关。
public interface List<T> { void add(T value); T get(int index); int size(); T remove(int index); void reverse(); } public class LinkedList<T> implements List<T> { private LLNode first, last; class LLNode { T value; LLNode next; LLNode(T value, LLNode next) { this.value = value; this.next = next; } T getLL(int index) { if (index == 0) { return value; } else { if (next == null) { throw new IndexOutOfBoundsException("error"); } return next.getLL(index - 1); } } T removeLL(int index) { if (next == null) { throw new IndexOutOfBoundsException("error"); } if (index == 1) { T value = next.value; next = next.next; return value; } else if (index > 1) { return next.removeLL(index - 1); } else { throw new IndexOutOfBoundsException("error"); } } void reverse(LLNode newNext) { if (next != null) { next.reverse(this); } this.next = newNext; } } @Override public void add(T value) { LLNode newNode = new LLNode(value, null); if (first == null) { first = last = newNode; } else { last.next = newNode; last = newNode; } } @Override public T get(int index) { if (first == null) { throw new IndexOutOfBoundsException("error"); } return first.getLL(index); } @Override public T remove(int index) { if (first == null) { throw new IndexOutOfBoundsException("error"); } if (index == 0) { T value = first.value; first = first.next; return value; } return first.removeLL(index); } @Override public void reverse() { if (first == null) { return; } first.reverse(null); LLNode tmp = last; //不明白这里 first.reverse 没有给 last 赋值,按理说这里 //last 的 next=null,但是为什么会是一个 next 等于 value=17 的 LLNode 类型数据呢 last = first; first = tmp; } public static void main(String[] args) { List<nteger> list = new LinkedList<>(); list.add(17); list.add(34); list.reverse(); } } 1 chenluo0429 2019 年 5 月 7 日 主要是要理解 LLNode 的 reverse()方法。 它从当前节点开始,将后面所有的节点顺序反转了。 ``` void reverse(LLNode newNext) { if (next != null) { next.reverse(this); } this.next = newNext; } |
2 user0506 OP @chenluo0429 我是这么理解的: 最初传入参数 newNext 为 null,第一次调用 next.reverse(17) ->17 下一个是 34,那么就变成了 34.reverse(17) -> 34.next=null, -> 再往后不满足 if 就结束了 17.next=null 有 34.next=17 所以变成了 34->指向 17->指向 null,因为调用的是 first.reverse(null),所以 first 变成了 value=34 next=17,last 不受影响 无论如何代码跟变量 last 也没什么关系啊,last 的初始值在被 add()动过后就不变了啊,应该还是 value=34, next=null,为什么执行完最后一次 this.next = newNext 后 last 的值就变了呢? 我觉得 reverse 反转的是节点的 next 值,但是 last 作为一个独立被赋值的变量,不应该受影响啊,真心求教。 |
3 user0506 OP @chenluo0429 我好像明白了,原来 last 里保存的不是值而是地址啊,这也就是为什么 reverse 修改了 node 的值的时候 last 变量跟着一起变了,我理解的对吗? |