链表是一种数据结构,其中元素包含对下一个(以及可选的前一个)元素的引用。链接列表提供O(1)插入和删除具有已知内存位置的任何元素,O(1)列表并置,以及前(和可选后)位置的O(1)访问以及O(1)下一个元素访问。随机访问和随机索引插入/移除具有O(n)复杂性并且通常是未实现的。
当结构体节点尚未定义时,C/CPP 如何知道如何指向“下一个”结构体节点? [重复]
创建单链表时,通常创建一个 Node 结构体,如下所示: 结构节点{ 整数数据; 结构节点*下一个; } 但是,我想知道指向下一个
LinkedList 可以使用升序或降序迭代器进行迭代,如下所示: LinkedList 列表 = new LinkedList(); ... StringJoiner sJ1 = new StringJoiner(" "); LinkedList 可以使用升序或降序迭代器进行迭代,如下所示: LinkedList<Object> list = new LinkedList<Object>(); ... StringJoiner sJ1 = new StringJoiner(" "); list.iterator().forEachRemaining(a -> sJ1.add(a.toString())); System.out.println("averse: \n" + sJ1.toString()); StringJoiner sJ2 = new StringJoiner(" "); list.descendingIterator().forEachRemaining(a -> sJ2.add(a.toString())); System.out.println("reverse: \n" + sJ2.toString()); averse: Hello 2 Chocolate 10 reverse: 10 Chocolate 2 Hello 但是 descendingIterator 不适用于 List 和 ArrayList。 是否有任何解决方法,或者至少有一个解释,为什么 descendingIterator 不在 List 中? 这个问题类似于可以在java中以相反的顺序执行foreach循环吗?。但所有答案都推荐临时解决方案或第三方库。 是否可以使用流来实现这一点? (不幸的是,我的谷歌搜索仅给出了流的缺乏标准反转如何反转Java 8流并生成值的递减IntStream?)。 正如我所提到的,我的问题与流有关,但是: 使用流只是一种选择;这个问题是关于 java.util.Iterator 和 java.util.List 该问题的答案仅解决了部分情况,但表明缺乏方便的一般逆向。如果我没有误用这些术语,List 是有序集合。 对 Comparable 项目进行排序以实现顺序会缩小范围。 没有充分的理由解释为什么 List 不能有一个降序迭代器。每个 List 都需要支持 ListIterator,可以使用 hasPrevious() 和 previous() 方法以相反顺序迭代。不过,这似乎是一个相当不常见的用例。 这里有一个小实用方法,可以将 Iterable 调整为 ListIterator 以相反顺序迭代: static <T> Iterable<T> descendingIterable(List<? extends T> list) { return () -> { ListIterator<? extends T> li = list.listIterator(list.size()); return new Iterator<T>() { public boolean hasNext() { return li.hasPrevious(); } public T next() { return li.previous(); } }; }; } 您可以使用它来实现您的示例: List<String> list = Arrays.asList("Hello", "2", "Chocolate", "10"); StringJoiner sj = new StringJoiner(" "); descendingIterable(list).iterator().forEachRemaining(sj::add); System.out.println(sj); 10 Chocolate 2 Hello 或者您可以在增强的 for 循环中使用它: for (String s : descendingIterable(list)) { System.out.println(s); } 10 Chocolate 2 Hello 我最初创建了一个 Iterator 而不是 Iterable,但后者更有用,因为它可以在增强的 for 循环中使用。 还请注意,这里有一个小问题,即如果 List 可以同时修改,则存在竞争条件。这发生在此处的代码中: list.listIterator(list.size()) 如果可能,您必须在列表上使用外部同步,或者如果列表是 CopyOnWriteArrayList,则必须先克隆它。有关后者的更多信息,请参阅此答案。 有关于为什么 List 中缺少 descendingIterator 的解释吗? 迭代列表的效率高度依赖于该列表的实现。 在设计接口时,您通常希望该接口适合其任何可能的实现。 Java 链表是一个双重链表,这意味着每个元素都链接到它之前和之后的元素,因此可以编写高效的升序和降序迭代器。 如果您使用singly链表,则降序迭代它的效率会非常低,您需要遍历整个列表,直到每次迭代的当前索引。 我怀疑正是由于这个原因,语言设计者决定从 List 接口中省略一个降序迭代器。 使用基于索引的方法可以相当轻松地实现高效的 ArrayList 降序迭代器,但在 LinkedList 上使用索引方法会比其首选实现慢得多。 降序迭代方法的一些示例: for(int i=list.size() -1; i >= 0; i--){ System.out.println(list.get(i)); } IntStream.range(0, list.size()) .map(i-> list.size() - 1 - i) .mapToObj(list::get) .forEach(System.out::println); 从 Java 21 开始,reversed() 方法可用于从列表中返回反转的 Iterator。 在 list.reversed().iterator() 可用于 List 和其他 list.descendingIterator() 类型的情况下,LinkedList 可用于任何 Deque 类型。 List<Object> list = new ArrayList<Object>(); // ... StringJoiner sJ1 = new StringJoiner(" "); list.iterator().forEachRemaining(a -> sJ1.add(a.toString())); System.out.println("averse: \n" + sJ1.toString()); StringJoiner sJ2 = new StringJoiner(" "); list.reversed().iterator().forEachRemaining(a -> sJ2.add(a.toString())); System.out.println("reverse: \n" + sJ2.toString()); 虽然它没有解释 为什么 没有一致的 descendingIterator,但 JEP 431:顺序集合 承认这是一个痛点,也是将 reversed() 方法引入 Java 的激励因素。 从头到尾迭代集合的元素是简单且一致的,但逆序迭代则不然。所有这些集合 [(表示具有定义的遇到顺序的元素序列)] 都可以使用 Iterator、增强的 for 循环、stream() 或 toArray() 向前迭代。每种情况下的反向迭代都是不同的。 NavigableSet 提供用于反向迭代的 descendingSet() 视图: for (var e : navSet.descendingSet()) process(e); Deque 则相反 Iterator: for (var it = deque.descendingIterator(); it.hasNext();) { var e = it.next(); process(e); } List 这样做,但是使用 ListIterator: for (var it = list.listIterator(list.size()); it.hasPrevious();) { var e = it.previous(); process(e); } 最后,LinkedHashSet不支持反向迭代。以相反顺序处理 LinkedHashSet 元素的唯一实用方法是将其元素复制到另一个集合中。
LinkedList 可以使用升序或降序迭代器进行迭代,如下所示: LinkedList 列表 = new LinkedList(); ... StringJoiner sJ1 = new StringJoiner(" "); 列表。 LinkedList 可以使用升序或降序迭代器进行迭代,如下所示: LinkedList<Object> list = new LinkedList<Object>(); ... StringJoiner sJ1 = new StringJoiner(" "); list.iterator().forEachRemaining(a -> sJ1.add(a.toString())); System.out.println("averse: \n" + sJ1.toString()); StringJoiner sJ2 = new StringJoiner(" "); list.descendingIterator().forEachRemaining(a -> sJ2.add(a.toString())); System.out.println("reverse: \n" + sJ2.toString()); averse: Hello 2 Chocolate 10 reverse: 10 Chocolate 2 Hello 但是 descendingIterator 不适用于 List 和 ArrayList。 是否有任何解决方法或列表解释,为什么List中缺少descendingIterator? 问题类似于可以在java中以相反的顺序执行foreach循环吗?。但所有答案都推荐临时解决方案或第三方库。 可能有可能使用流流吗? (不幸的是,我的谷歌搜索仅给出了流缺乏标准反向Java 8流反向顺序) 正如我所提到的,我的问题与流有关,但是: 使用流只是一种选择,问题是关于 java.util.Iterator 和 java.util.List 该问题的答案仅解决了部分情况,但表明缺乏方便的一般逆向。如果我没有遗漏术语列表是有序集合,对可比较项目进行排序,以实现顺序会缩小范围。 没有充分的理由解释为什么 List 不能有一个降序迭代器。每个 List 都需要支持 ListIterator,可以使用 hasPrevious() 和 previous() 方法以相反顺序迭代。不过,这似乎是一个相当不常见的用例。 这里有一个小实用方法,可以将 Iterable 调整为 ListIterator 以相反顺序迭代: static <T> Iterable<T> descendingIterable(List<? extends T> list) { return () -> { ListIterator<? extends T> li = list.listIterator(list.size()); return new Iterator<T>() { public boolean hasNext() { return li.hasPrevious(); } public T next() { return li.previous(); } }; }; } 您可以使用它来实现您的示例: List<String> list = Arrays.asList("Hello", "2", "Chocolate", "10"); StringJoiner sj = new StringJoiner(" "); descendingIterable(list).iterator().forEachRemaining(sj::add); System.out.println(sj); 10 Chocolate 2 Hello 或者您可以在增强的 for 循环中使用它: for (String s : descendingIterable(list)) { System.out.println(s); } 10 Chocolate 2 Hello 我最初创建了一个 Iterator 而不是 Iterable,但后者更有用,因为它可以在增强的 for 循环中使用。 还请注意,这里有一个小问题,即如果 List 可以同时修改,则存在竞争条件。这发生在此处的代码中: list.listIterator(list.size()) 如果可能,您必须在列表上使用外部同步,或者如果列表是 CopyOnWriteArrayList,则必须先克隆它。有关后者的更多信息,请参阅此答案。 有关于为什么 List 中缺少 descendingIterator 的解释吗? 迭代列表的效率高度依赖于该列表的实现。 在设计接口时,您通常希望该接口适合其任何可能的实现。 Java 链表是一个双重链表,这意味着每个元素都链接到它之前和之后的元素,因此可以编写高效的升序和降序迭代器。 如果您使用singly链表,则降序迭代它的效率会非常低,您需要遍历整个列表,直到每次迭代的当前索引。 我怀疑正是由于这个原因,语言设计者决定从 List 接口中省略一个降序迭代器。 使用基于索引的方法可以相当轻松地实现高效的 ArrayList 降序迭代器,但在 LinkedList 上使用索引方法会比其首选实现慢得多。 降序迭代方法的一些示例: for(int i=list.size() -1; i >= 0; i--){ System.out.println(list.get(i)); } IntStream.range(0, list.size()) .map(i-> list.size() - 1 - i) .mapToObj(list::get) .forEach(System.out::println); 从 Java 21 开始,reversed() 方法可用于从列表中返回反转的 Iterator。 在 list.reversed().iterator() 可用于 List 和其他 list.descendingIterator() 类型的情况下,LinkedList 可用于任何 Deque 类型。 List<Object> list = new ArrayList<Object>(); // ... StringJoiner sJ1 = new StringJoiner(" "); list.iterator().forEachRemaining(a -> sJ1.add(a.toString())); System.out.println("averse: \n" + sJ1.toString()); StringJoiner sJ2 = new StringJoiner(" "); list.reversed().iterator().forEachRemaining(a -> sJ2.add(a.toString())); System.out.println("reverse: \n" + sJ2.toString()); 虽然它没有解释 为什么 没有一致的 descendingIterator,但 JEP 431:顺序集合 承认这是一个痛点,也是将 reversed() 方法引入 Java 的激励因素。 从头到尾迭代集合的元素是简单且一致的,但逆序迭代则不然。所有这些集合 [(表示具有定义的遇到顺序的元素序列)] 都可以使用 Iterator、增强的 for 循环、stream() 或 toArray() 向前迭代。每种情况下的反向迭代都是不同的。 NavigableSet 提供用于反向迭代的 descendingSet() 视图: for (var e : navSet.descendingSet()) process(e); Deque 则相反 Iterator: for (var it = deque.descendingIterator(); it.hasNext();) { var e = it.next(); process(e); } List 这样做,但是使用 ListIterator: for (var it = list.listIterator(list.size()); it.hasPrevious();) { var e = it.previous(); process(e); } 最后,LinkedHashSet不支持反向迭代。以相反顺序处理 LinkedHashSet 元素的唯一实用方法是将其元素复制到另一个集合中。
在 Rust 中,如何将一个大向量分配到链表而不发生堆栈溢出?
我正在做 LeetCode 的第 234 题。我有一个函数,它将链表作为输入: 实现解决方案{ pub fn is_palindrome(mut head: Option>) -> bool { 一个...
获取链表孪生值的最大和 孪生值意味着第一个应该与最后一个相加,第二个应该与倒数第二个相加 等式1,2,3,4 然后 1+4 和 2+3
公共静态SinglyLinkedListNode insertNodeAtPosition(SinglyLinkedListNode llist,int数据,int位置){ 如果(列表==空){ llist = new SinglyLinkedListNode(数据); 返回...
我正在尝试从堆栈中弹出一个项目(使用链接列表而不是数组)。我首先创建了一个 LinkedList 类,其中包含 3 个节点,其值为 [1,2,3]。所以我想弹出最后一个节点(n...
下面是我的“Snake 项目”(使用 Turtle 和 Tkinter)的 Python 代码。 该程序的目的是创建一条称为追随者的海龟链,它们相互跟随,并带有 fi...
向大家问好。我正在为我的 DSA 课程开发一个图书馆管理应用程序。我们使用 Borland Graphics.h 库来绘制用户界面(从该图中可以看出)。从...
我正在尝试使用链表添加 2 个稀疏矩阵。 我接受 2 个矩阵的值 将它们相加并将它们存储到第三个矩阵中。 但由于某种原因,这些值没有存储在 l...
对于给定的 RefCell,RefCell::as_ptr 是否保证保持不变?
我正在寻找一种为 MyStruct 实现哈希的方法,其中 MyStruct 包含`Rc(是的,它是某种链接列表)。 这个答案建议 std::ptr::hash(self.next.as_ref()),但我有......
我正在Python中使用两个列表实现一个链表 - 一个用于存储值,一个用于存储指针,这样节点在值中具有其值,并且它指向的值存储在其对应项中...
我一直在研究 Leetcode #23: Merge K Sorted Lists (https://leetcode.com/problems/merge-k-sorted-lists/description/) 并遇到一个问题。 我知道一个可行的解决方案是使用 d...
我在堆栈溢出内外的几篇文章中看到了弗洛伊德算法的几个证明。所有这些都证明了算法的第二部分,即为什么要找到
在 java.util.LinkedList 类中,定义了 2 个构造函数,默认构造函数和参数化构造函数接受集合。 当我查看实现时,我发现参数化构造函数具有
LinkedList数据结构,为什么我们需要从不同的构造函数调用空的默认构造函数
在 java.util.LinkedList 类中,定义了 2 个构造函数,默认构造函数和参数化构造函数接受集合。当我查看实现时,我发现参数化构造函数具有
我有一个奇怪的问题,无法遍历自定义链接列表。下面是遍历的代码。 从输入 import 可选 类列表节点: def __init__(self, val, next_node=None): ...
#包括 #包括 int main(空) { typedef 结构节点 { 整数; 结构节点*下一个; }节点; // 创建指向 main 的指针...
我正在Python中使用两个数组实现一个链表 - 一个用于存储值,一个用于存储指针,这样节点的值就存储在值中,而它指向的值存储在其
为了好玩,我尝试用 lambda 函数创建一个链表。我尝试了这个小代码作为第一步,但是在面临无限循环后我的实验很快就结束了: 导入迭代工具 堆栈=...