簡體   English   中英

Java中的雙向循環鏈接列表

[英]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;}
}

現在,您有一個headertrailer偽節點:

header <--> first <--> second <--> ... <--> last <--> trailer

相反,您必須在兩個方向上都連接第一個和最后一個。

        .-> first  <--> second <--> ... <--> last <-.
        |                                           |
        '-------------------------------------------'

或者,您也可以在一個節點中合並標題和尾部,但是這不是“純”循環鏈接列表,因為在遍歷時您必須跨過標題/尾部節點。

        .-> first  <--> second <--> ... <--> last <--> header/trailer <-.
        |                                                               |
        '---------------------------------------------------------------'

循環列表沒有標題,結尾,第一個或最后一個元素。 這會迫使您遇到特殊情況。

您可以擁有一個偽元素,也可以沒有。

如果您有偽元素,則需要在getNextgetPrevious中將其作為特殊情況處理,因為必須跳過它,但是您不必擔心列表為空或要刪除某些內容時會發生什么重要。

如果沒有偽元素,則下一個和上一個沒有特殊情況,但是當列表為空時,則有添加的特殊情況;如果刪除了用於鏈接到列表的節點,則有特殊的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM