【问题标题】:Can I use java.util.LinkedList to construct a circular/cyclic linked list?我可以使用 java.util.LinkedList 构造循环/循环链表吗?
【发布时间】:2011-04-14 02:51:05
【问题描述】:

我想创建一个循环/循环链表,其中链表的尾部将指向链表的头部。那么我可以使用java.util.LinkedList 并在创建列表后修改尾节点以使其循环/循环吗?如果是这样,你能告诉我一些关于如何发生的代码吗?

如果我不能使用java.util.LinkedList,我应该如何创建自己的循环/循环链表实现?你能告诉我这个实现的框架吗?

如果您需要更多详细信息,请告诉我,我会解决任何困惑。

【问题讨论】:

  • 为什么要循环链表?
  • 我只是想制作一个。没有真正的原因,除了我自己。我还没有在网上看到很多这样的实现,我只是想试一试。
  • @puddingfox:循环列表对于集合的循环访问很有用(例如,用于负载平衡)
  • @user359996:循环使用循环列表只是一种好的编程实践吗?我知道“圆形”和“圆形”是一起使用的,但是在数组列表上使用循环列表还有其他原因吗?
  • 如何实现循环列表并不是很重要。就您而言,我个人会使用 ArrayList,然后用 docs.guava-libraries.googlecode.com/git-history/release/javadoc/… 包装它。编辑:显然,这甚至是有人给出的答案之一......

标签: java data-structures linked-list circular-list


【解决方案1】:
class ListNode {
    public ListNode next;
    public Object data;

    public ListNode(Object data, ListNode next) {
        this.next = next;
        this.data = data;
    }
}

class CircularLinkedList {
    private ListNode head = null;
    private int numberOfElements = 0;
    private ListNode actualElement = null;
    private int index = 0;

    public boolean isEmpty() {
        return (numberOfElements == 0);
    }

    public int getNumberOfElements() {
        return numberOfElements;
    }

    public void insertFirst(Object data) {
        if (!(isEmpty())) {
            index++;
        }
        ListNode listNode = new ListNode(data, head);
        head = listNode;
        numberOfElements++;
    }

    public void insertAfterActual(Object data) {
        ListNode listNode = new ListNode(data, actualElement.next);
        actualElement.next = listNode;
        numberOfElements++;
    }

    public boolean deleteFirst() {
        if (isEmpty())
            return false;
        if (index > 0)
            index--;
        head = head.next;
        numberOfElements--;
        return true;
    }

    public boolean deleteActualElement() {
        if (index > 0) {
            numberOfElements--;
            index--;
            ListNode listNode = head;
            while (listNode.next.equals(actualElement) == false)
                listNode = listNode.next;
            listNode.next = actualElement.next;
            actualElement = listNode;
            return true;
        }
        else {
            actualElement = head.next;
            index = 0;
            return deleteFirst();
        }
    }

    public boolean goToNextElement() {
        if (isEmpty())
            return false;
        index = (index + 1) % numberOfElements;
        if (index == 0)
            actualElement = head;
        else
            actualElement = actualElement.next;
        return true;
    }

    public Object getActualElementData() {
        return actualElement.data;
    }

    public void setActualElementData(Object data) {
        actualElement.data = data;
    }
}

【讨论】:

  • deleteActualElement 方法中有两个小错误,我已经更正了。
【解决方案2】:

对于实际应用(例如,不仅仅是玩耍或学习)我个人更喜欢 Guava 的 Iterables.cycle 方法 - 请参阅 Iterables.cycle

【讨论】:

    【解决方案3】:

    java.util.LinkedList 是 Collections 数据类型之一。 Collections 的目的是提供实用结构,而不是让程序员担心它们的内部实现。如果您必须拥有以某种方式工作的内部结构,而 java.util 不能保证它们是这样工作的,那么它们不适合你。

    要实现循环链​​表,首先要创建一个ListNode类:

    class ListNode {
        ListNode next;
        ListNode prev;
        Object data;
    }
    

    然后存储一个ListNode head,并确保headprev指向列表的“end”,而“end”的next又指向head。不过,老实说,保持尾指针的双向链表和循环链表之间几乎没有区别。

    【讨论】:

    • 我不需要“双向”链表,所以不需要ListNode prev。不过谢谢你的建议。我试试看。
    猜你喜欢
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多