【发布时间】:2012-01-26 10:47:27
【问题描述】:
1) 我可以在 C 中不使用指针(并且不使用结构)创建链接列表吗?
2) Java 不使用指针,那么链表是如何在 Java 中实现的?
【问题讨论】:
-
你查过
java.util.LinkedList的来源吗?
标签: java c linked-list
1) 我可以在 C 中不使用指针(并且不使用结构)创建链接列表吗?
2) Java 不使用指针,那么链表是如何在 Java 中实现的?
【问题讨论】:
java.util.LinkedList的来源吗?
标签: java c linked-list
【讨论】:
CompressedOops 称为指针。 NullPointerException 是一个不幸的命名选择,Bloch(我认为)说他应该把它命名为 NullReferenceException.. 有一件事 C# 固定在那里;)
如果您可以忍受一些愚蠢的限制,例如列表具有固定的最大长度并预先分配所有潜在元素,您可以使用索引来替换指针。
这可以使元素本身更小,因为如果您知道元素数量的良好边界(您必须这样做,以便预分配工作),您可以调整索引的大小,但您可以不要用指针来做到这一点。对于最多包含 1,000 个元素的列表,您可能会使用 uint16_t 索引,它是 64 位架构上指针大小的 1/4。
另一方面,索引涉及地址计算,仅在跟随直接指针时不需要,因此可能会有性能成本。
【讨论】:
至于1,我觉得不可能。
对于 2,你应该看看这个优秀的资源http://cslibrary.stanford.edu/
【讨论】:
对于 java - 它是 LinkedList 正在使用的引用 http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html
【讨论】:
1 - 不。链表的关键在于它是动态数据结构。这意味着您可以在运行时更改其大小(而不是在编译程序时必须知道它的大小)。这只能通过指针来完成,因为当您分配一些新内存时,您需要知道如何找到它。
你可以不使用结构体,但它们是最合适的结构体。
2 - Java 有对对象的引用。它们基本上和指针一样,只是你不能用它们做算术,而且它们是类型安全的。
【讨论】:
1 - 绝对。使用一组并行数组(每个属性一个)并使用数组索引作为指针。一代又一代的 FORTRAN 程序员(以及像我这样向那些 FORTRAN 程序员学习的大学生)将这种方法用于各种数据结构 - 列表、树、堆栈、队列等。它很丑陋,它是一个巨大的痛苦,它有一些真正的限制,但这当然是可能的。指针类型和聚合类型使数据结构的实现更容易,但它们几乎不是必需的。
2 - Java 到处都使用指针;它只是不向程序员公开指针类型的操作。任何时候你使用引用类型(基本上,任何需要你使用new 来创建实例的东西)你都在使用指针。
【讨论】:
1) 由于所有内存分配都涉及到指针,并且您需要为列表中的新条目分配额外的内存,因此无法实现随元素数量增长和收缩的传统链表。
2) Java 有references,和指针一样,只是不能对它们进行指针运算(如int* p = q + 1;)。
【讨论】:
structs 的链表?也许。你可以有一组数组,一个包含数据,另一个包含下一个节点的索引。当然,数组使用指针。【讨论】:
1) 如果您绝对必须这样做,建议“愚蠢的限制”的答案可能是您最好的选择,尽管其中一些限制完全破坏了使用链表的意义。例如,容易调整大小变得不可能调整大小。为什么你不想使用指针?
2) 仅仅因为您没有看到它们并不意味着它们不存在。更准确的说法是“我不必在 Java 中处理指针或它们的算术运算”。如果您需要向自己证明指针在幕后,请使用 int 和 Integer 执行以下过程
0) (我们是优秀的代码负责人)声明并将变量初始化为 3 1)打印它 2)将它传递给另一个函数 3)在该函数中增加它 4)再次打印 5) 返回 6) 从调用函数打印。
对于 int 类型,您将打印 3 4 3,对于 Integer,您将打印 3、4、4。这是因为对象是通过引用传递的,这意味着您仍在处理底层的指针。参考是不同的,因为(在大多数情况下)您不必处理它们。
【讨论】: