鏈式數據

1.特點

    通過指針連接起來的結點存儲數據元素;

2. 節點結構由數據域和指針域組成

   

3.分類

  3.1 單鏈表

    

   說明,頭部指向第一個元素的地址,第一個元素指針域指向第二個元素,依次指向,最後一個元素指針域爲空,沒有指向其它元素,這樣的節點通過指針域構成起來的鏈表稱爲單鏈表

3.2 循環鏈表

  最後一個元素的指針域指向頭部構成一個元素鏈表

 3.3 雙鏈表

    

   有兩個指針域,記住前一個元素的地址和後一個元素的地址,可以從雙向遍歷元素,相比於單鏈表遍歷方式增加靈活性,但是佔用多一個指針域空間

4.單鏈表插入和刪除示意圖

 4.1 在單鏈表中插入結點

   插入新元素c,把a元素的指針域指向c元素,把c元素的指針指向b元素

 4.2 單鏈表中刪除元素

  

   刪除b元素,a元素指向b元素的指針改成指向c元素

5.Java語言實現鏈式

 5.1 說明:定義一個靜態內部類Node,稱爲結點,結點與結點相連在一起構成鏈式數據結構,每個結點有兩個數據域,一個指向數據,另一個指向另外一個結點

5.2 在包中定義一個靜態內部類

/**
 * 定義一個嵌套類,嵌套類與內部類的區別在於嵌套類是靜態,內部類不是靜態
 * @param <E>
 */
private static class Node<E> {
    /**
     * 指向對象一個引用,結點的數據部分
     */
    E data;
    /**
     * 指向下一個結點引用
     */
    Node next;
    public Node(E data, Node next) {
        this.data = data;
        this.next = next;
    }
}

5.3 外部類添加方法

/**
 * 添加元素方法
 * @param e
 * @return
 */
public boolean add(E e){
    //創建一個新結點,數據域保持數據對象
    Node<E> newNode = new Node<>(e);
    //記下前面一個結點地址
    newNode.next = first;
    //把當前結點賦給頭結點
    first = newNode;
    size ++;
    return true;
}

 測試效果如下:

  

 封裝的數據格式如下:  

6.簡單代碼示意

public class CustomLinkedList<E> {

    /**
     * 頭引用,指向第一個元素
     */
    private Node first;

    /**
     * 記錄元素的個數
     */
    private int size;


    /**
     * 添加元素方法
     * @param e
     * @return
     */
    public boolean add(E e){
        //創建一個新結點,數據域保持數據對象
        Node<E> newNode = new Node<>(e);
        //記下前面一個結點地址
        newNode.next = first;
        //把當前結點賦給頭結點
        first = newNode;
        size ++;
        return true;
    }

    public Object[] toArray(){
        Object[] result = new Object[size];
        int i = 0;
        for(Node<E> e = first;e != null; e = e.next){
            result[i++] = e.data;
        }
        return result;
    }

    /**
     * 判斷結點鏈中數據域是否等於給定的值
     * @param e
     * @return
     */
    public boolean contains(E e){
        if(e == null){
            return false;
        }
        boolean found = false;
        Node<E> currentNode = first;
        while(!found && currentNode != null){
            if(e.equals(currentNode.data)){
                found = true;
            }else {
             currentNode = currentNode.next;
            }
        }
        return found;
    }

    /**
     * 基本思路是刪除一個結點,並將頭引入指向第二結點
     * @return
     */
    public E remove(){
        E result = null;
        if(first != null){
            //讀取頭結點數據域
            result = (E)first.data;
            //將頭結點指向第二個結點
            first = first.next;
            size --;
        }
        return result;
    }

    /**
     * 1.用鏈中的第一個結點數據域替換要移除值所在的結點
     * 2.從鏈中刪除第一個結點
     * @param e
     * @return
     */
    public boolean remove(E e){
        boolean result = false;
        Node<E> currentElementNode = getReferenceNode(e);
        if( currentElementNode != null){
            //當前結點數據域保持第一個結點數據域
            currentElementNode.data = (E)first.data;
            //移除第一個結點
            first = first.next;
            size --;
            result = true;
        }
        return result;
    }

    /**
     * 清空鏈表
     */
    public void clear(){
        while (!isEmpty()){
            remove();
        }
    }

    /**
     * 判斷是否爲空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 根據給定的元素,獲取該元素在鏈中的結點引用
     * @param e
     * @return
     */
    private Node<E> getReferenceNode(E e){
        boolean found = false;
        Node<E> currentNode = first;
        while (!found && currentNode != null){
            if(e.equals(currentNode.data)){
                found = true;
            }else {
                currentNode = currentNode.next;
            }
        }
        return currentNode;
    }


    /**
     * 定義一個嵌套類,嵌套類與內部類的區別在於嵌套類是靜態,內部類不是靜態
     * @param <E>
     */
    private static class Node<E> {
        /**
         * 指向對象一個引用,結點的數據部分
         */
        E data;
        /**
         * 指向下一個結點引用
         */
        Node next;

        public Node(E data) {
            this.data = data;
        }

        public Node(E data, Node next) {
            this.data = data;
            this.next = next;
        }
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章