[英]Doubly Circularly Linked Lists in Java
我正在尝试实现一个双向循环链接列表,但有点迷茫; 我有我的双向链接列表,但不确定如何使其循环发送。 我已经读过,只有最后一个节点指向第一个节点,所以就像这样:
public void addLast(DNode v) {
addAfter(header, v);
}
这是我的双向链接列表的代码:
public class Dlist {
protected int size;
protected DNode header, trailer;
public Dlist() {
size = 0;
header = new DNode(null, null, null);
trailer = new DNode(null, header, null);
header.setNext(trailer);
}//end DList()
public int size() { return size; }
public boolean isEmpty() { return (size == 0); }
public DNode getFirst() throws IllegalStateException {
if (isEmpty()) throw new IllegalStateException("List is empty");
return header.getNext();
}//end isEmpty
public DNode getLast() throws IllegalStateException {
if (isEmpty()) throw new IllegalStateException("List is empty");
return trailer.getPrev();
}//end getLast
public DNode getPrev(DNode v) throws IllegalArgumentException {
if (v == header) throw new IllegalArgumentException
("Cannot move back past the header of the list");
return v.getPrev();
}
public DNode getNext(DNode v) throws IllegalArgumentException {
if (v == trailer) throw new IllegalArgumentException
("Cannot move forward past the trailer of the list");
return v.getNext();
}
public void addBefore(DNode v, DNode z) {
DNode u = getPrev(v);
z.setPrev(u);
z.setNext(v);
v.setPrev(z);
u.setNext(z);
size++;
}
public void addAfter(DNode v, DNode z) {
DNode w = getNext(v);
z.setPrev(v);
z.setNext(w);
w.setPrev(z);
v.setNext(z);
size++;
}
public void addFirst(DNode v) {
addAfter(header, v);
}
public void addLast(DNode v) {
addBefore(trailer, v);
}
public void remove(DNode v) {
DNode u = getPrev(v);
DNode w = getNext(v);
w.setPrev(u);
u.setNext(w);
v.setPrev(null);
v.setNext(null);
size--;
}
public boolean hasPrev(DNode v) { return v != header;}
public boolean hasNext(DNode v) { return v != trailer; }
public String toString() {
String s = "[";
DNode v = header.getNext();
while (v != trailer ) {
s += v.getElement();
v = v.getNext();
if (v != trailer) {
s += ",";
}
s+= "]";
return s;
}
return s;
}
编辑:DNode;
public class DNode {
protected String element;
protected DNode next, prev;
public DNode(String e, DNode p, DNode n) {
element = e;
prev = p;
next = n;
}
public String getElement() {return element;}
public DNode getPrev() { return prev; }
public DNode getNext() { return next; }
public void setElement(String newElem) { element = newElem; }
public void setPrev(DNode newPrev) { prev = newPrev; }
public void setNext(DNode newNext) {next = newNext;}
}
现在,您有一个header
和trailer
伪节点:
header <--> first <--> second <--> ... <--> last <--> trailer
相反,您必须在两个方向上都连接第一个和最后一个。
.-> first <--> second <--> ... <--> last <-.
| |
'-------------------------------------------'
或者,您也可以在一个节点中合并标题和尾部,但是这不是“纯”循环链接列表,因为在遍历时您必须跨过标题/尾部节点。
.-> first <--> second <--> ... <--> last <--> header/trailer <-.
| |
'---------------------------------------------------------------'
循环列表没有标题,结尾,第一个或最后一个元素。 这会迫使您遇到特殊情况。
您可以拥有一个伪元素,也可以没有。
如果您有伪元素,则需要在getNext
和getPrevious
中将其作为特殊情况处理,因为必须跳过它,但是您不必担心列表为空或要删除某些内容时会发生什么重要。
如果没有伪元素,则下一个和上一个没有特殊情况,但是当列表为空时,则有添加的特殊情况;如果删除了用于链接到列表的节点,则有特殊的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.