1. 程式人生 > 實用技巧 >03-java實現迴圈連結串列

03-java實現迴圈連結串列

03java實現迴圈連結串列

本人git https://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);
    // 如果 index == size, 說明新增的索引是最後位置
    if (index == size) {
    	// 建立新節點, prev指向原連結串列的尾節點, next指向首節點
    	Node<E> node = new Node<>(last, element, first);
    	// 當原連結串列沒有任何節點
    	if (size == 0) {
            first = node;
            last = node;
            node.prev = node;
            node.next = node;
        }else {
            // 原連結串列尾節點next指向node
            last.next = node;
            // 原連結串列頭結點prev指向node
            first.prev = node;
            // last指向新的尾節點
            last = node;
        }
    }else {
        // 新增新節點後的下一個節點
        Node<E> next = node(index);
        // 新增新節點後的上一個節點
        Node<E> prev = next.prev;
        // 建立新節點, 新節點的上一個節點時prev, 新節點的下一個節點是next
        Node<E> node = new Node<>(prev, element, next);
        // next的上一個節點是新節點
        next.prev = node;
        // prev的下一個節點是新節點
        prev.next = node;
        // 當next == first時, 說明新新增節點的索引是0
        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;
        // 如果node == first, 說明刪除的是第一個節點
        if (node == first) {
            first = next;
        }
        // 如果next == last, 說明刪除的是最後一個節點
        if (next == last) {
            last = prev;
        }	
    }
    size--;
    return node.element;
}