所以我有链接节点堆栈的代码(简称链接堆栈),它让我非常困惑!我明天参加考试,这让我很困惑!所以看看:
class Node<T> {
T item; // data in node
Node<T> next = null; // successor node
Node(T item0, Node<T> next0) {
item = item0; next = next0;
}
}
这很容易理解没问题,我们创建一个名为Node的类(它是一个数据结构),它包含一个类型为T
的项(可以是String,Integer等......)和另一个{{1}调用 next 来表示下一个节点。一切都很清楚。关闭!
现在是Node
本身的时间,所以这里是代码:
Stack
现在我失去了理智!好的!首先,当我们启动堆栈时,我们创建一个名为 head 的class Stack<T> {
private Node<T> head = null; // first node (null if empty)
Stack() {}
Stack(int n) {}
boolean isEmpty() {return(head==null);}
boolean push(T t) {
head = new Node<>(t,head);
return true; // always space available
}
T pop() {
if (head==null) return null;
T t = head.item;
head = head.next;
return t;
}
}
好吧!得到它,它是Node
是的!接下来,当我们使用null
方法时,黑魔法就是我。所以我们说push(T t)
没问题好吧!慢慢下来的家伙!我们将现有的head = new Node<>(t, head)
head 替换为包含数据 t 的新节点,并将 next 节点替换为自身? ?所以head = data,head(null,null)..?如果我们添加第二个元素怎么办?它将再次成为head = data,head(数据,head(null,null)......?
请用简单的英语向我解释一下! :(
答案 0 :(得分:2)
该行
head = new Node<>(t,head);
按顺序执行
1)new Node<>(t,head)
2)head = ...
因此,当您创建新的Node
对象时,您会传递旧值head
,而不是对自身的引用。
为了减少混淆,可以将此行重写为
Node<T> oldHead = head;
head = new Node<>(t, oldHead);
当堆栈为空时head = null
当我们添加一个项目head = (item1, null)
时
当我们添加另一个项head = (item2, (item1, null))
答案 1 :(得分:1)
Node
创建的push
不包含对自身的引用。当您在Java中执行赋值时,分配的变量(在等号的左侧)不会改变,直到之后右侧的所有内容都被完全解析和构建。
因此,在Java执行Node
构造函数以创建新的head
节点时,head
对象中的Stack
值仍然指向到前一个头。因此,使用新数据创建了head
的新节点,以及对上一个 head
节点的引用。然后,只有在完全创建新的Node
对象(并且next
值指向前一个head
)之后,head
中的值才会Stack
} object被分配给新创建的对象。
答案 2 :(得分:1)
我认为你在想这个。因此堆栈的工作方式类似于链表。所以如果你有一个空列表,head = null。你得到了那个部分。
所以当你调用push时你正在做的是将新节点添加到顶部,因此它将成为新的头节点。 head = new Node&lt;&gt;(t,HEAD); 现在,新节点位于列表的顶部,Node的第二个参数(即HEAD)指向作为链表头部的旧节点。
所以在第一次推动时,不难理解: 第一次调用push:head = new node(t,NULL),因为旧的head节点是NULL
第二次调用push:head = new node(t,head)和head(这里的第二个参数)指向旧头部,现在是列表中的下一个项目
答案 3 :(得分:1)
当您执行head = new Node<>(t, head)
时,您正在使用Node
和Node.item = t
将堆叠头部更新为Node.next = oldHead
,在这种情况下为null
因为你没有放任何东西。
如果我们向空堆栈添加1个元素,我们得到Node(data1,null)。如果我们向堆栈添加第二个项,我们得到Node(data2,Node(data1,null))