數據結構之簡單鏈表

作力扣 的算法題 忽然想到這個數據結構,以爲有必要記錄下來java

1. 定義一個Link類和一個Node類,其中Node類爲Link類的內部類(避免了反覆的getter和setter方法)
Link類的目的是進行節點建立
Node類的目的是進行數據和節點連接,而且Node只能爲Link調用,須要定義爲private
再定義一個Factory類,用來給客戶端調用,返回的是一個Link類的實例node

2. Node類中須要包含有如下屬性:
    (1) Object data : 用於存放數據
    (2) Node next : 用戶存放指向下一個節點的數據
構造函數就是給data賦值
3. 增長1個追加函數,往鏈表中添加元素
    (1) 明確的是,追加數據要在Link類中完成
    (2) 須要先在Link類中聲明root根節點
    (3) 若是沒有傳入數據,那麼就直接返回,不作操做
    (4) 對於存放的數據,那麼就要新建一個節點,新建一個節點對象,而後把這個節點對象交給Node類去處理
    (5) 第4步中,存放節點數據應該從root開始,若是root爲空,那麼存放的數據就是root,只要把新建節點賦值給root便可
        若是不是,那麼就要把新建節點交由Node類處理,從root節點開始
    (6) Node類接收Link類傳過來的newNode對象,作如下處理:
        判斷root的next是否爲空值,如果,則把newnode賦值給root.next
        若不爲空,那麼遞歸,下個是root.next.next
以上完成增長一個數據,並處理節點關係
測試程序爲:
//
public class TestLinkDemo {
    public static void main(String[] args) {
        Link all = Factory.getInstance();
        all.add("AAA");
        all.add("BBB");
        all.add("CCC");
    }
}
//
4. 增長一個函數,獲取鏈表中的數據個數
    (1) 在Link類中定義屬性,統計個數,count
    (2) 定義方法,獲取count,就是返回數據個數
    (3) 定義isEmpty()方法,判斷鏈表是否爲空
5. 增長一個函數,能夠把鏈表轉換成對象數組
    (1) 鏈表就是一個動態數組,返回類型爲Object[] data,每一個數據的取得有前後順序,所以須要定義一個遊標
    (2) Link類中,首先須要判斷,鏈表長度是否爲零,若是是零,就返回空值,若是不是0,則須要遍歷整個鏈表,
        遊標爲0,從root節點開始調用Node中取出數據的函數(新定義)
    (3) Node類中須要獲取每一個節點的數據,並填寫到數組中,若是判斷下個節點還有數據,那麼就要繼續遞歸
6. 增長一個查詢數據的方法
    (1) 須要equals方法支持
    (2) Node中追加一個方法,用於查找指定元素,並且必須從root節點開始日後找
    (3) Link中追加一個方法,用於判斷必須輸入查找內容,以及鏈表不爲空,若正常,就調用Node中的方法,從root開始
    
7. 根據索引取得數據
    (1) 在Node類裏面增長一個索引查找的方法,根據遊標查找
    (2) 在Link類中增長一個索引查找方法,目的是保證鏈表有數據,同時初始化遊標,查找的時候從root節點日後找算法

8. 修改指定索引的數據
    (1) 首先在Link類中定義一個方法,傳入2個參數,第一個爲索引值,第二個是要修改爲的目標對象值
        考慮問題,若是索引超過了鏈表長度,那麼就不修改,結束調用
        不然就先設定遊標,而後從root節點開始調用Node中真正修改數據的函數
    (2) Node類中定義的方法,首先判斷當前遊標是否爲指定遊標,如果,則修改數據
        若不是,判斷當前是否是最後一個節點,若是節點不爲空,那麼繼續日後查找節點,遞歸調用數組

9. 刪除數據
    (1) 全部的前提是存在該數據,全部首先由上面定義的查找方法進行查找
        若是刪除的是根節點,更換root的操做只須要在Link類中完成便可
        若是不是,那麼要把根節點的下一個節點交給Node類中的刪除方法進行
    (2) Node類中判斷當前對象的數據是不是要刪除的數據,若是是的話,就把這個對象的上一個next指向下一個next數據結構

        若是不是,則繼續遞歸刪除函數

 

更新一下查找方法,原課程寫的有問題測試

//根據索引取得數據
    public Object getNode(int searchIndex) {
      if (Link.this.index++ == searchIndex) {
        return this.data;
      } else {
        return this.next.getNode(searchIndex);
      }
    }
class Link {
    private Node root; //根節點,增長數據函數添加
    private int count; //統計元素個數
    private Object[] retData; //返回對象數組
    private int index = 0; //操做遊標
    // 定義Node內部類,表示Node只爲Link類服務
    private class Node { //負責 保存數據,節點關係配置
        private Object data;
        private Node next;
        public Node(Object data) {
            this.data = data;
        }
        //增長數據
        public void addNode(Node newNode) {
        if (this.next == null) {
            this.next = newNode;
        } else {
            this.next.addNode(newNode);
        }
        }
        //轉換成對象數組
        public void toArrayNode() {
            Link.this.retData[Link.this.index ++] = this.data;//先把root節點的數據取出,而後遊標加一
            if (this.next != null){ //若是下個節點還有數據,則遞歸獲取
                this.next.toArrayNode();
            }
        }
        //查找數據
        public boolean containsNode(Object search) {
            if (search.equals(this.data)) {
                return true; //找到數據
            } else {
                if (this.next != null) { //還有後續節點
                    return this.next.containsNode(search);//遞歸查找
                } else {
                    return false;
                }
            }
        }
        //根據索引取得數據
        public Object getNode(int searchIndex) {
            if (Link.this.index ++ == searchIndex) {
                return this.data;
            } else {
                this.next.getNode(searchIndex);
            }
            return null;
        }
        //修改指定索引的數據
        public void setNode(int searchIndex, Object newData) {
            if (Link.this.index ++ == searchIndex) {
                this.data = newData;
            } else {
                if (this.next != null) {
                    this.next.setNode(searchIndex,newData);
                }
            }
        }
        //刪除元素
        public void removeDataNode(Node previous, Object data) {
            if (this.data.equals(data)) {
                previous.next = this.next; //中間是this,若是this的data是所要刪除的data,那麼把this以前的一個node指向this以後的一個node
            } else {
                this.next.removeDataNode(this, data);
            }
        }
    }
    // ---------如下是Link類定義-----------
    //增長元素
    public void add(Object data) {
        if ( data == null ) {//不容許存放空值數據
            return;
        }
        Node newNode = new Node(data); //建立一個新的節點
        if (this.root == null) {
            this.root = newNode;
        } else {
            this.root.addNode(newNode);
        }
        this.count ++;
    }
    //獲取鏈表大小
    public int size() {
        return this.count;
    }
    //判斷鏈表是否爲空
    public boolean isEmpty() {
        if (this.root == null && this.count == 0 ) {
            return false;
        } else {
            return true;
        }
    }
    //鏈表轉換成對象數組
    public Object[] toArray() {
        if (this.count == 0) { //若是鏈表沒有數據,那麼就返回null
            return null;
        }
        this.retData = new Object[this.count];//若是count不爲零,那麼開闢指定空間的對象數組
        this.index = 0;//遊標初始化爲0
        this.root.toArrayNode();//交給Node類進行數據的取出
        return this.retData;//返回對象數組
    }
    //查找數據
    public boolean contains(Object search) {
        if (search == null || this.root == null) {
            return false;
        }
        return this.root.containsNode(search);
    }
    //根據索引取得數據
    public Object get(int searchIndex) {
        if (searchIndex >= this.count) {
            return null;
        }
        this.index = 0;
        return this.root.getNode(searchIndex);
    }
    //修改指定索引的數據
    public void setData(int searchIndex, Object newData) {
        if (searchIndex >= this.count) {
            return ;
        } else {
            this.index = 0;
            this.root.setNode(searchIndex, newData);
        }
    }
    //刪除數據
    public void removeData(Object data) {
        if (this.contains(data)) {
            if (this.root.data.equals(data)) {
                this.root = this.root.next;
            } else {
                this.root.next.removeDataNode(this.root, data);
            }
            this.count --;
        }
    }
            
}
 
class Factory {
    public static Link getInstance() {
        return new Link();
    }
}
 
public class TestLinkDemo {
    public static void main(String[] args) {
        Link all = Factory.getInstance();
        //
        all.add("AAA");
        all.add("BBB");
        all.add("CCC");
        //
        System.out.println("鏈表大小爲: " + all.size());
        //
        Object[] result = all.toArray();
        System.out.println("鏈表轉換成對象數組並輸出: ");
        for ( Object x : result ) {
            System.out.println(x);
        }
        //查詢數據方法
        System.out.println("查詢數據方法: ");
        System.out.println(all.contains("AAA"));
        System.out.println(all.contains("D"));
        //取得索引數據
        System.out.println("查找索引爲0的數據: ");
        System.out.println(all.get(0));
        System.out.println("查找索引爲3的數據: ");
        System.out.println(all.get(3));
        //修改索引數據
        System.out.println("修改索引數據: ");
        all.setData(0,"DDD");
        Object[] result1 = all.toArray();
        System.out.println("修改索引數據並輸出: ");
        for ( Object x : result1 ) {
            System.out.println(x);
        }
        //刪除數據
        System.out.println("刪除數據: ");
        all.removeData("BBB");
        Object[] result2 = all.toArray();
        System.out.println("刪除數據並輸出: ");
        for ( Object x : result2 ) {
            System.out.println(x);
        }
    }
}

   


測試結果:this

相關文章
相關標籤/搜索