为了存储图(邻接列表),我必须为一个类创建一个链表数组。我们必须使用Java。我可以创建数组并实例化每个链表,但当我向每个链表添加第一个元素时,每个链表都会发生更改,而不仅仅是数组索引处的链表。
Node [] adjList;
for(i=0;i<adjList.length;i++)
adjList[i] = new Node(0,0,null);
这实例化了每个新的链表[Node
是我自己的类,带有构造函数Node(int head, int data, Node next
),并扩展了LinkedList
]
然后我将第一个值添加到每个节点:
for(i=0;i<adjList.length;i++)
adjList[i].setHead(i+1); // numbers 1 to end are the graph vertices
或
for(i=0;i<adjList.length;i++)
adjList[i].add(new Node(i+1,0,null);
我使用print语句调试代码在这些循环结束时,我打印出每个链表,但对于每个链表,值都是最后一个
即。如果adjList.length = 2
,它将打印出
[3,0,null] // adjList[0]
[3,0,null] // adjList[1]
[3,0,null] // adjList[2]
编辑:这是节点类
import java.util.LinkedList;
public class Node extends LinkedList{
private static int head;
private static int data;
private static Node next;
public Node(int h,int d,Node n) {
head = h;
data = d;
next = n;
}
public int getHead(){ // getNext() and getData() are the same
return head;
}
public void setHead(int h){ // setNext() and setData() are basically the same
head = h;
}
}
您可能已经将Node
中的某些内容声明为静态,因此每个实例最终都具有相同的共享值,而不是具有自己的值。然而,这只是一个猜测-请发布Node
的代码,这样我们就可以看到真正的问题是什么…
当我将第一个元素添加到每个元素时,每个链表都会发生更改,而不仅仅是数组索引处的链表
尽管您的代码片段没有显示它,但几乎可以肯定的是,您存在混叠问题。在几乎所有面向对象的语言中,混淆问题都会困扰初学者,它是指用两个不同的名称引用同一对象的问题,即两个不同变量指向同一对象。
现在您可能想知道:数组索引呢?问题是在一个数组索引处更改变量,然后在所有数组索引中进行更改,而不是在一堆命名变量中进行更改。但是,正如Eric Lippert所解释的(对于C#,它与Java非常相似),数组实际上是一组变量,您可以用索引器表达式引用这些变量,而不必定义一组单独的名称。从某种意义上说,int[] foo = new int[3]
类似于声明foo0
、foo1
和foo2
,而对foo
进行索引只是"告诉"编译器从foo0
、foo1
和foo2
中选择适当的变量。
您可能还想知道,如果您的数组中确实有多个节点,那么如何在多个Node
实例之间共享数据。有几种方法,并且知道如果没有Node
类的代码,哪种方法几乎是不可能的。正如@DNA所指出的,Node
类中可能存在静态数据,它会在所有实例中自动共享。CCD_ 18对象还可以具有对底层数据的引用。如果将相同的引用传递到所有Node
构造函数中,那么它们也会以这种方式对同一对象进行混叠。