六種方法的實現:
package list;
import java.util.ArrayList;
import java.util.List;
/**
*@author Edward
*@date 2020年6月30日---下午2:32:40
*/
public class LinkedList<E> {
private Node head;
private int size;
class Node{
E data;
Node prev;
Node next;
Node(E e) {
data=e;
}
}
public boolean add(E e) {
Node node = new Node(e);
if (head==null) {
head = node;
head.next = head;
head.prev = head;
size++;
return true;
}
Node last = head.prev;
last.next = node;
node.prev = last;
head.prev = node;
node.next = head;
size++;
return true;
}
public void add(int index,E e) {
if (index<0||index>size) {
throw new IndexOutOfBoundsException("下標越界啦");
}
Node node = new Node(e);
if (head==null) {
head=node;
// 當head是唯一節點時,必須設置前後爲自己(其默認值均爲null),否則toString遍歷中會空指針
head.next = head;
head.prev = head;
size++;
return;
}
Node next = getNode(index);
Node prev = next.prev;
node.next = next;
next.prev = node;
prev.next = node;
node.prev = prev;
if (index == 0) {
head = node;
}
size++;
}
public String toString() {
if (head==null) {
return "[]";
}
Node dummyHead = new Node(null);
dummyHead.next = head;
List<E>list = new ArrayList<E>();
do {
dummyHead = dummyHead.next;
list.add(dummyHead.data);
} while (dummyHead.next!=head);
return list.toString();
}
public int size() {
return size;
}
public E get(int index) {
if (index<0||index>=size) {
throw new IndexOutOfBoundsException("下標越界啦");
}
Node node = getNode(index);
return node.data;
}
public E remove(int index) {
if (index<0||index>=size) {
throw new IndexOutOfBoundsException("下標越界啦");
}
// 這個雙向循環鏈表的很多操作是基於頭節點的,因此可能影響head的操作需要特殊處理
// 邊界條件,如果整個鏈表只有一個節點,需設置頭節點爲null
if (size==1) {
E data = head.data;
head = null;
size--;
return data;
}
Node node = getNode(index);
node.prev.next = node.next;
node.next.prev = node.prev;
size--;
// 邊界條件,如果刪除的是頭節點,需重新設置一個頭節點
if (index==0) {
head=node.next;
}
return node.data;
}
private Node getNode(int index) {
Node node = head;
if (index<size/2) {
for (int i = 0; i < index; i++) {
node = node.next;
}
}else {
for (int i = size; i > index; i--) {
node= node.prev;
}
}
return node;
}
}