【问题标题】:implementing circular linked list with java generics用java泛型实现循环链​​表
【发布时间】:2018-09-12 16:02:06
【问题描述】:

我正在学习 java,我还是个初学者。我编写了这段代码来实现一个循环链表,当我尝试打印列表时,它会不断打印数字。它看起来像是某种无限循环。我什至尝试使用调试,但它对我没有多大作用。如果您可以查看代码并了解发生这种情况的原因,我将非常感激。这是下面的代码。我也会给我关于代码的反馈:) 这是循环链表的类

public class CircularLinkedList<E> implements API<E> {
    private Node<E> head;
    private int size = 0;

    public void placeAtBeginning(E element) {
        Node<E> newNode = new Node<E>(element);
        if(head == null) {
            head = newNode;
            head.setNext(head);
        }else {
            Node<E> temp = head;
            head = newNode;
            newNode.setNext(temp);
        }
        size++;
    }

    public void placeAtEnd(E element) {
        Node<E> newNode = new Node<E>(element);
        if (head == null) {
            head = newNode;
        }else {
            Node<E> temp = head;
            while (temp.getNext() != head) {
                temp = temp.getNext();
            }
            temp.setNext(newNode);
        }

        newNode.setNext(head);
        size++;
    }

    public void deleteFromBeginning() {
        Node<E> temp = head;
        while (temp.getNext() != head) {
            temp = temp.getNext();
        }
        temp.setNext(head.getNext());
        head = head.getNext();
        size --;
    }

    public void deleteFromEnd() {
        Node<E> temp = head;
        while(temp.getNext().getNext() != head) {
            temp = temp.getNext();
        }
        temp.setNext(head);
        size--;
    }

    public void print() {
        Node<E> temp = head;
        while(temp.getNext()!= head) {
            System.out.print(temp.getValue() + " , ");
            temp = temp.getNext();
        }
        System.out.print(temp.getValue());
    }
}

这是我的节点的类

public class Node<T> {
    private Node<T> next;
    private T item;

    public Node(T item) {
        this.item = item;
    }

    public void setNext(Node<T> next) {
        this.next = next;
    }

    public Node<T> getNext() {
        return this.next;
    }

    public T getValue() {
        return this.item;
    }
}

这是我尝试使用 int 测试它的主要部分。

public class Main {
    public static void main(String [] args) {
        API <Integer> list = new CircularLinkedList<Integer>();

        int a = 10;
        int b = 3;
        int c = 15;
        int d = 8;
        int f = 9;

        list.placeAtBeginning(a);
        list.placeAtEnd(b);
        list.print();
        System.out.println();
        list.placeAtBeginning(c);
        list.placeAtBeginning(d);
        list.print();
    }
}

这是我使用的 API

public interface API <E> {
    public void placeAtBeginning(E element);
    public void placeAtEnd(E element);
    public void deleteFromBeginning();
    public void deleteFromEnd();
    public void print();
}

【问题讨论】:

  • 无限循环是使用调试器单步执行代码的完美情况。
  • 我试过了,但它在 Eclipse 上不起作用。感谢您的反馈
  • 解释“不工作”。是代码没有下断点,还是你找不到无限循环本身?
  • 这意味着你的链表中有一个循环,因为插入/删除没有正确执行。每次插入/删除节点时,使用调试器单步执行代码,并检查指针排列是否完全符合您的预期。
  • 查看placeAtBeginning():如果原始循环列表不为空,则新的头部成为新元素,而新元素的next引用原始循环列表。换句话说,它不会在现有圈子中插入新元素。您应该搜索最后一个元素(“next”指的是 head)并更新该元素的“next”。

标签: java generics data-structures linked-list abstract-data-type


【解决方案1】:

您的方法placeAtBeginning() 不会在循环列表中插入新元素,而只是让新元素的next 引用原始循环列表。

试试这个:

public void placeAtBeginning(E element)
{
  Node<E> newNode = new Node<E>(element);
  if(head == null)
  {
    head = newNode;
    head.setNext(head);
  }
  else
  {
    Node<E> last = head;
    while (last.getNext() != head)
      last = last.getNext();
    newNode.setNext(head);
    head = newNode;
    last.setNext(head);
  }
  size++;
}

我没有检查其他方法。它们可能包含类似的错误。

【讨论】:

  • 谢谢。这行得通。我错过了关于尾巴指向开始的部分:)
  • 如果您要频繁插入和删除元素,特别是如果列表包含大量元素,我建议您在类中添加一个属性,以跟踪最后一个节点列表。这是因为在每个操作中您都需要搜索它。
猜你喜欢
  • 1970-01-01
  • 2012-09-02
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 2012-06-06
相关资源
最近更新 更多