手寫雙向鏈表LinkedList的幾個經常使用功能

實現的功能以下:
1)建立鏈表
2)添加節點(默認添加和指定位置添加)
3)訪問某一個節點
4)刪除節點
5)得到鏈表的長度大小
6)判斷鏈表是否爲空
7)自定義鏈表的打印格式
8)清空鏈表node

*注意:要弄清楚節點的前赴 和 後繼,刪除時要注意賦值的順序!!!app

定義 鏈表中 節點的類Nodeide

public class Node {
    
    /**
     * 值
     * 
     */
    Object value;
    
    /**
     * 前驅
     */
    Node pre;
    
    /**
     * 後繼
     */
    Node next;
    
    public Node(){
        
    }
    
    public Node(Object value, Node pre, Node next) {
        this.value = value;
        this.pre = pre;
        this.next = next;
    }
}

定義雙向鏈表LinkList,實現功能以下:工具

/**
 * 雙向鏈表
 * 
 * @author min
 *
 */
public class LinkList {

    /**
     * 頭結點
     */
    private Node head;
    
    /**
     * 尾結點
     */
    private Node tail;
    
    private int size;
    
    public LinkList() {
        head = new Node();
        tail = new Node();
        
        head.next = tail;
        tail.pre = head;
        size = 0;
        
    }
    
    public int size() {
        return size;
    }
    
    public boolean isEmpty() {
        return size==0;
    }
    
    public void clear() {
        head.next = tail;
        tail.pre = head;
        size = 0;
    }
    
    /**
     * 在末尾添加新的數據
     * 
     * @param value 數據
     */
    public void add(Object value) {
        Node node = new Node(value,tail.pre,tail);
        tail.pre.next = node;
        tail.pre = node;
        size ++;
        }
    
    /**
     * 在特意位置建立新的節點
     * @param index
     * @param value
     */
    public void add(int index, Object value) {
        checkLinkList(index);
        
        if(index == size -1) {
            //插在最後一位
            add(value);
        }
        else{
            Node x = node(index-1);
            Node y = node(index);
            Node node = new Node(value, x, y);
            x.next = node;
            y.pre = node;
            size ++;
        }        
    }
    
    /**
     * 獲取特定位置的節點
     * @param index
     * @return 節點存儲的值
     */
    public Object get(int index) {
        //檢查是否在鏈表內
        checkLinkList(index);
        //節點的值
        return node(index).value;
    }

    /**
     * 刪除特定的節點
     * @param index
     * @return 被刪除的節點
     */
    public Node remove(int index) {
        checkLinkList(index);
        Node x = node(index);
        x.pre.next = x.next;
        x.next.pre = x.pre;
        size --;
        return x;
    }
    

    /**
     * 檢查索引是否在鏈表內
     * 
     * @param index
     */
    private void checkLinkList(int index) {
        if(index > size() ||index < 0)
            throw new ArrayIndexOutOfBoundsException(index);
    }

    /**
     * 遍歷鏈表查詢特定的節點
     * 
     * @param index 索引
     * @return 指定的節點
     */
    private Node node(int index) {
        //第1個節點
        Node firstNode = head;
        //最後1個節點
        Node lastNode = tail;
        
        //從頭開始遍歷
        if(index <=(size>>1) ) {
            Node indexNode = firstNode;
            for(int i = -1; i < index; i++)
                indexNode = indexNode.next;
            return indexNode;
        }
            
        //從尾遍歷
        else{            
            Node indexNode = lastNode;
            for(int i = size; i>index; i--) {
                indexNode = indexNode.pre;
            }
            return indexNode;
        }        
    }
    
    /**
     * 重寫鏈表輸出方式
     * 
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        String str = "";
        for(int i = 0; i<size; i++) {
            str = String.valueOf(i + ":"+ node(i).value + "\n");
            builder.append(str);
        }
        return builder.toString();
    }    
}

測試
圖片描述測試


只實現了一些經常使用功能,本身寫的和工具包中的類對比,會從中get到不少。受益多多~ui

相關文章
相關標籤/搜索