1. 程式人生 > 實用技巧 >2020年9月21日 手動實現單向連結串列

2020年9月21日 手動實現單向連結串列

package com.atguigu.test03;

public class SingleLinkedList {
    //這裡不需要陣列,不需要其他的複雜的結構,我只要記錄單向連結串列的“頭”結點
    private Node first;//first中記錄的是第一個結點的地址
    private int total;//這裡我記錄total是為了後面處理的方便,例如:當用戶獲取連結串列有效元素的個數時,不用現數,而是直接返回total等
    
    /*
     * 內部類,因為這種Node結點的型別,在別的地方沒有用,只在單向連結串列中,用於儲存和表示它的結點關係。
     * 因為我這裡涉及為內部型別。
     
*/ private class Node{ Object data;//因為資料可以是任意型別的物件,所以設計為Object Node next;//因為next中記錄的下一個結點的地址,因此型別是結點型別 //這裡data,next沒有私有化,是希望在外部類中可以不需要get/set,而是直接“結點物件.data","結點物件.next"使用 Node(Object data, Node next){ this.data = data; this.next = next; } }
public void add(Object obj){ /* * (1)把obj的資料,包裝成一個Node型別結點物件 * (2)把新結點“連結”當前連結串列的最後 * ①當前新結點是第一個結點 * 如何判斷是否是第一個 if(first==null)說明暫時還沒有第一個 * ②先找到目前的最後一個,把新結點連結到它的next中 * 如何判斷是否是最後一個 if(某個結點.next == null)說明這個結點是最後一個 */ // (1)把obj的資料,包裝成一個Node型別結點物件
//這裡新結點的next賦值為null,表示新結點是最後一個結點 Node newNode = new Node(obj, null); //①當前新結點是第一個結點 if(first == null){ //說明newNode是第一個 first = newNode; }else{ //②先找到目前的最後一個,把新結點連結到它的next中 Node node = first; while(node.next != null){ node = node.next; } //退出迴圈時node指向最後一個結點 //把新結點連結到它的next中 node.next = newNode; } total++; } public int size(){ return total; } public Object[] getAll(){ //(1)建立一個數組,長度為total Object[] all = new Object[total]; //(2)把單向連結串列的每一個結點中的data,拿過來放到all陣列中 Node node = first; for (int i = 0; i < total; i++) { // all[i] = 結點.data; all[i] = node.data; //然後node指向下一個 node = node.next; } //(3)返回陣列 return all; } public void remove(Object obj){ if(obj == null){ //(1)先考慮是否是第一個 if(first!=null){//連結串列非空 //要刪除的結點正好是第一個結點 if(first.data == null){ //讓第一個結點指向它的下一個 first = first.next; total--; return; } //要刪除的不是第一個結點 Node node = first.next;//第二個結點 Node last = first; while(node.next!=null){//這裡不包括最後一個,因為node.next==null,不進入迴圈,而node.next==null是最後一個 if(node.data == null){ last.next = node.next; total--; return; } last = node; node = node.next; } //單獨判斷最後一個是否是要刪除的結點 if(node.data == null){ //要刪除的是最後一個結點 last.next = null; total--; return; } } }else{ //(1)先考慮是否是第一個 if(first!=null){//連結串列非空 //要刪除的結點正好是第一個結點 if(obj.equals(first.data)){ //讓第一個結點指向它的下一個 first = first.next; total--; return; } //要刪除的不是第一個結點 Node node = first.next;//第二個結點 Node last = first; while(node.next!=null){//這裡不包括最後一個,因為node.next==null,不進入迴圈,而node.next==null是最後一個 if(obj.equals(node.data)){ last.next = node.next; total--; return; } last = node; node = node.next; } //單獨判斷最後一個是否是要刪除的結點 if(obj.equals(node.data)){ //要刪除的是最後一個結點 last.next = null; total--; return; } } } } public int indexOf(Object obj){ if(obj == null){ Node node = first; for (int i = 0; i < total; i++) { if(node.data == null){ return i; } node = node.next; } }else{ Node node = first; for (int i = 0; i < total; i++) { if(obj.equals(node.data)){ return i; } node = node.next; } } return -1; } }
package com.atguigu.test03;

import java.util.Arrays;

public class TestSingleLinkedList {

    public static void main(String[] args) {
        SingleLinkedList list = new SingleLinkedList();
        
        list.add("張三");
        list.add("李四");
        list.add("王五");
        list.add("趙六");
        list.add("錢七");
        
        System.out.println("元素個數:" + list.size());
    
        Object[] all = list.getAll();
        System.out.println(Arrays.toString(all));
        
        /*list.remove("張三");
        System.out.println("元素個數:" + list.size());
        all = list.getAll();
        System.out.println(Arrays.toString(all));
        
        list.remove("王五");
        System.out.println("元素個數:" + list.size());
        all = list.getAll();
        System.out.println(Arrays.toString(all));
        
        list.remove("錢七");
        System.out.println("元素個數:" + list.size());
        all = list.getAll();
        System.out.println(Arrays.toString(all));*/
        
        System.out.println(list.indexOf("張三"));
        System.out.println(list.indexOf("王五"));
        System.out.println(list.indexOf("錢七"));
    }

}