1. 程式人生 > >資料結構(三)——單向迴圈連結串列的java實現

資料結構(三)——單向迴圈連結串列的java實現

單向迴圈連結串列結構就是連結串列的最後一個指標不再是null,而是指向整個連結串列的第一個結點,使連結串列形成一個環。
這裡寫圖片描述

上程式碼

package likend;

/**
 * Created by yxf on 2018/3/27.
 * 單向迴圈連結串列
 */
public class CycleLink<T> {

    private Node header;  //連結串列頭結點
    private Node tail;    //連結串列尾結點
    private int size;     //儲存已經有的結點

    public class Node
<T> {
private T data; //資料 private Node next; //指向下一個節點的引用 public Node() { } public Node(T data, Node next) { this.data = data; this.next = next; } } public CycleLink() { } /** * 在尾部新增 * * @param
element * @return */
public boolean add(T element) { linkLast(element); return true; } /** * 獲取指定索引處的元素 * * @param index * @return */ public T getElement(int index) { return (T) getNodeByIndex(index).data; } /** * 獲取指定位置的結點 * @param
index * @return */
public Node getNodeByIndex(int index){ if (index < 0 || index > size) throw new IndexOutOfBoundsException("獲取位置超過了連結串列長度範圍"); Node currentNode = header; for (int i = 0; i < index; i++) { currentNode = currentNode.next; } return currentNode; } /** * 獲取指定位置前驅的結點 * @param index * @return */ public Node getNodeByIndexBefore(int index){ Node preNode = header; for (int i = 0; i < index - 1; i++) { preNode = preNode.next; //獲得前驅結點 } return preNode; } /** * 獲取指定元素的前驅 * * @param currentElem * @return */ public T priorElement(T currentElem) { int index = getIndex(currentElem); if (index == -1) return null; else { if (index == 0) { return null; } else { return (T) getNodeByIndex(index - 1).data; } } } /** * 獲取指定元素的後驅 * * @param currentElem * @return */ public T nextElement(T currentElem) { int index = getIndex(currentElem); if (index == -1) return null; else { if (index == size - 1) { return null; } else { return (T) getNodeByIndex(index + 1).data; } } } public int getIndex(T element) { Node current = header; for (int i = 0; i < size && current != null; i++, current = current.next) { if (current.data.equals(element)) return i; } return -1; } /** * 在頭部插入 * * @param element * @return */ public boolean addFirst(T element) { linkFirst(element); return true; } /** * 在指定位置插入元素 * * @param index * @param element * @return */ public boolean insert(int index, T element) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("插入位置超出連結串列範圍"); if (index == 0) linkFirst(element); else { Node preNode = getNodeByIndexBefore(index); Node newNode = new Node(element, null); newNode.next = preNode.next; preNode.next = newNode; size++; } return true; } /** * 刪除元素 * * @param index * @return */ public T delete(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("刪除位置超出連結串列範圍"); Node currentNode = header; if (index == 0) { header = header.next; currentNode.next = null; tail.next = header; } else { Node currentNodeBefore = null; for (int i = 0; i < index; i++) { currentNodeBefore = currentNode;//前置結點 currentNode = currentNode.next; //要刪除的當前結點 } //刪除的是尾結點 if(index == size - 1){ tail = currentNodeBefore; //尾結點變為刪除結點的前置結點 tail.next = header; }else { currentNodeBefore.next = currentNode.next; } currentNode.next = null; } size--; return (T) currentNode.data; } //刪除最後一個元素 public T remove(){ return delete(size-1); } /** * 尾部插入 * * @param e */ private void linkLast(T e) { final Node<T> l = tail; final Node<T> newNode = new Node<>(e, null); if (l == null) { header = newNode; tail = header; } else { tail.next = newNode; //尾結點指向新結點 newNode.next = header; //新結點指向頭結點 tail = newNode; //新結點作為尾結點 } size++; } private void linkFirst(T e) { final Node<T> l = header; Node<T> newNode = new Node<>(e, null); if (l == null) { header = newNode; tail = header; } else { newNode.next = header; //新結點指向header header = newNode; //新結點稱為頭結點 tail.next = header; //尾結點指向頭結點 } size++; } public boolean isEmpty() { return size == 0; } //清空線性表 public void clear(){ //將頭結點和尾結點設為空 header = null; tail = null; size = 0; } @Override public String toString() { if (isEmpty()) return "[]"; else { StringBuilder sb = new StringBuilder("["); sb.append(header.data + "->").toString(); if (header.next != null) { for (Node current = header.next; current != header; current = current.next) sb.append(current.data + "->").toString(); } int len = sb.length(); return sb.delete(len - 2, len).append("]").toString(); } } }
  • 測試CycleLinkTest
package likend;

/**
 * Created by yxf on 2018/3/27.
 */
public class CycleLinkTest {

    public static void main(String[] args) {
        CycleLink ls = new CycleLink();
        ls.add(2);
        ls.add(4);
        ls.add(5);
        ls.addFirst(1);
        System.out.println("新增元素後的連結串列為: "+ls);
        ls.insert(2,3);
        System.out.println("在連結串列位置2插入元素: "+ls);
        ls.delete(2);
        System.out.println("在連結串列位置2刪除元素: "+ls);
        ls.remove();
        System.out.println("刪除連結串列中的一個元素: "+ls);
        System.out.println("獲得連結串列位置為2處的元素:   "+ ls.getElement(2));
        System.out.println("獲取元素2的前驅元素:    "+ls.priorElement(2));
        System.out.println("獲取元素2的後驅元素:    "+ls.nextElement(2));
        ls.clear();
        System.out.println(ls);
    }
}

測試結果

新增元素後的連結串列為: [1->2->4->5]
在連結串列位置2插入元素: [1->2->3->4->5]
在連結串列位置2刪除元素: [1->2->4->5]
刪除連結串列中的一個元素: [1->2->4]
獲得連結串列位置為2處的元素:   4
獲取元素2的前驅元素:    1
獲取元素2的後驅元素:    4
[]

Process finished with exit code 0