03-java實現循環鏈表
03java實現循環鏈表
本人git //github.com/bigeyes-debug/Algorithm
一丶單向循環鏈表

二丶單向循環鏈表的介面設計
- 比較單向鏈表,單向循環鏈表只需要修改添加節點,刪除節點兩個方法,也就是add和remove方法
三丶單向循環鏈表的實現
3.1添加節點
- 相比於單向鏈表,單向循環鏈表只需要特別關注插入頭結點的情況即可
- 需要考慮的特殊情況是當鏈表的長度為0的時候的插入的情況

public void add(int index, E element) {
rangeCheckForAdd(index);
if (index == 0) {
Node<E> newFirst = new Node<>(element, first);
Node<E> last = (size == 0) ? newFirst : node(size - 1);
last.next = newFirst;
first = newFirst;
} else {
Node<E> prev = node(index - 1);
prev.next = new Node<>(element, prev.next);
}
size++;
}
3.2刪除節點
- 如果刪除的是頭節點,刪除後需讓last指向新的頭節點。
- 當只有一個節點並刪除時, first指向null。
public E remove(int index) {
rangeCheck(index);
Node<E> node = first;
if (index == 0) {
if (size == 1) {
first = null;
} else {
Node<E> last = node(size - 1);
first = first.next;
last.next = first;
}
} else {
Node<E> prev = node(index - 1);
node = prev.next;
prev.next = node.next;
}
size--;
return node.element;
}
四、雙向循環鏈表

五、雙向循環鏈表介面設計
- 相較於雙向鏈表,雙向循環鏈表需要重寫插入節點、刪除節點兩個方法。
六丶雙向循環鏈表接的實現
6.1插入節點
- 需特殊處理添加第一個元素和添加到尾節點兩種特殊情況。
public void add(int index, E element) {
rangeCheckForAdd(index);
if (index == size) {
Node<E> node = new Node<>(last, element, first);
if (size == 0) {
first = node;
last = node;
node.prev = node;
node.next = node;
}else {
last.next = node;
first.prev = node;
last = node;
}
}else {
Node<E> next = node(index);
Node<E> prev = next.prev;
Node<E> node = new Node<>(prev, element, next);
next.prev = node;
prev.next = node;
if (next == first) {
first = node;
}
}
size++;
}
6.2刪除節點
- 刪除節點,就是在環上去掉某一個節點,然後根據刪除的節點是首節點或者尾節點來處理first和last。
- 需要特殊處理只有一個節點的刪除操作。
public E remove(int index) {
Node<E> node = node(index);
if (size == 1) {
first = null;
last = null;
}else {
Node<E> prev = node.prev;
Node<E> next = node.next;
next.prev = prev;
prev.next = next;
if (node == first) {
first = next;
}
if (next == last) {
last = prev;
}
}
size--;
return node.element;
}