如何在java中实现循环链表?

如何在java中实现循环链表?,java,data-structures,Java,Data Structures,我读了一本关于“数据结构和算法”的书,书中有一个作业要求我实现一个循环链表。这是一个学习练习,我的代码可能不是很高的标准 我实现循环链表的主要思想是有一个指向最后一个元素的指针,每次我添加新项目时,最后一个项目的字段“next”将刷新以指向新添加的项目 插入方法可以很好地工作,我可以毫无问题地添加项,但由于某些原因,我无法从列表中删除项 以下是“链接”或“节点”的代码: public class Link { public long data; public Link next;

我读了一本关于“数据结构和算法”的书,书中有一个作业要求我实现一个循环链表。这是一个学习练习,我的代码可能不是很高的标准

我实现循环链表的主要思想是有一个指向最后一个元素的指针,每次我添加新项目时,最后一个项目的字段“next”将刷新以指向新添加的项目

插入方法可以很好地工作,我可以毫无问题地添加项,但由于某些原因,我无法从列表中删除项

以下是“链接”或“节点”的代码:

public class Link {
  public long data;
  public Link next;

  public Link(long val) {
    data = val;
    next = null;
  }

  public void displayLink() {
    System.out.print(data + " ");
  }

}  // end class
这是执行该工作的类的代码,错误显然在这里的某个地方:

public class CircularList {
Link first;
Link last;

public CircularList() {
     first = null;
     last = null;
}

public Link find(long key) {
    Link current = first;
    while(current.data != key) {
        current = current.next;
    }
    return current;
} // end find

public Link delete() {
    if(first.next == null) 
        last = null;
    Link temp = first;
    first = first.next;
    return temp;
}  // end delete

public boolean isEmpty() { return (first == null); }

public void insert(long val) {
    Link newLink = new Link(val);

    if(isEmpty())
        last = newLink;

    newLink.next = first;
    first = newLink;
    last.next = first;
} // end insert

public void displayAmount(int n) {
    Link current = first;
    while(n>0) {
        current.displayLink();
        current = current.next;
        n--;
    }
    System.out.println("");
} // end displayAmount

}  // end class
和主应用程序代码:

public class App {
public static void main(String[] args) {
    CircularList cl = new CircularList();

    cl.insert(10);
    cl.insert(20);
    cl.insert(30);
    cl.insert(40);

    cl.displayAmount(6);

    cl.delete();

    cl.displayAmount(6);
}
}  // end class
显示量看起来有点傻,我只是试图避免无限循环,并做了一些简单的事情。您的
delete()
方法无法处理列表的循环性。最后一个元素指向第一个元素;当删除第一个元素时,也需要更新

换句话说,您需要将
last.next
设置为指向新的
first
而不是旧的
first

另一个问题是,如果删除最后一个元素(使其现在为空),则还需要将
last
设置为
null

public Link delete() {
    if (first.next == null) {
        first = null;
        last = null;
    }
    Link temp = first;
    first = first.next;
    last.next = first;
    return temp;
} 

在delete()函数中,将
last.next=first
添加到
return temp
之前:

public Link delete() {
    if(first.next == null) 
        last = null;
    Link temp = first;
    first = first.next;
    if(last != null)
        last.next = first
    return temp;
} 
更新:

我找不到满足
first.next==null
的场景,我们应该考虑在空列表上调用delete()

public Link delete() {
    Link temp = first;
    if(first == null){
        ;  // or you can throw some exception as a warning
    }
    else if(first==last){  // only one element
        first = null; // reset to initial state
        last = null;
    }
    else{
        first = first.next;
        last.next = first;
    }
    return temp;
} 

您的问题是什么?您的链表节点缺少对上一个节点的引用,因此无法删除。您希望最后一个元素引用第一个元素以及第一个到最后一个元素,这意味着两者都需要下一个和上一个元素。有了这些,您可以获取任何元素,获取当前元素的上一个和下一个,并将上一个与下一个连接起来,从而有效地删除要删除的元素。@G_V使用
delete()
方法,因为它总是(尝试)删除第一个元素,这是正常的,因为它的前一个元素是
last
。如果要删除任意元素,则需要将其双重链接,但如果只删除
第一个
,则不需要该链接。此链接可能对您有所帮助,您不需要
null
检查:如果
first
不是null,则
last
也不能为null(因为如果您只有一个元素,那么
first==last
)@chiastic security只要first.next==null可能是真的,我想我们需要null检查,因为我们将last设置为null。但是,我注意到这可能永远不会发生,因此我更新了我的答案,并为我们删除的另一个案例添加了防御代码()在一个空的列表上。你的变体也在起作用。至少对我来说,它清楚地传达了这个想法。