1. 程式人生 > >Java實現單鏈表及相關操作

Java實現單鏈表及相關操作

單鏈表是一種鏈式存取的資料結構,用一組地址任意的儲存單元存放線性表中的資料元素。連結串列中的資料是以結點來表示的。

每個結點的構成:元素(資料元素的映象) + 指標(指示後繼元素儲存位置),

  • 元素就是儲存資料的儲存單元,

  • 指標就是連線每個結點的地址資料。

單鏈表結構圖:

先建一個結點類

/**
 * @auther: lawt
 * @date: 2018/11/4 08
 * @Description: 結點資訊
 */
public class Node {
    /**
     * 為了方便,這兩個變數都使用public,而不用private就不需要編寫get、set方法了。
     * 存放資料的變數,簡單點,直接為int型
     */
    public int data;
    /**
     * 存放結點的變數,預設為null
     */
    public Node next;

    /**
     * 構造方法,在構造時就能夠給data賦值
     */
    public Node(int data) {
        this.data = data;
    }
}

 

相關操作

/**
 * 插入頭結點
 */
public static void insertHead(Node head, Node newHead) {
    Node old = head;
    head = newHead;
    head.next = old;
}

/**
 * 插入尾節點
 */
public static void insertTail(Node tail, Node newTail) {
    Node old = tail;
    tail = newTail;
    tail.next = null;
    old.next = tail;
}

/**
 * 遍歷
 *
 * @param head 連結串列
 */
public static void query(Node head) {
    while (head != null) {
        System.out.print(head.data + " ");
        head = head.next;
    }
    System.out.println();
}

/**
 * 查詢某個結點
 *
 * @param head 頭結點
 * @param data 要找的node的data
 * @return 連結串列下標
 */
public static int find(Node head, int data) {
    int index = -1;//初始值為-1
    int count = 0;//可以知道迴圈次數
    while (head != null) {//當頭結點部位null
        if (head.data == data) {//如果該節點的值==找的
            index = count;
        }
        count++;//沒有找到,迴圈次數+1
        head = head.next;//沒有找到繼續遍歷
    }
    return index;//返回連結串列下標
}

/**
 * 插入
 *
 * @param p 插入到p的後
 * @param s 需要插入的node
 */
public static void insert(Node p, Node s) {
    Node next = p.next;//記錄下p結點
    p.next = s;//p的next指向s結點
    s.next = next;//把p結點的next指向s的next結點
}

/**
 * 刪除結點q
 *
 * @param head 連結串列
 * @param q    刪除的結點
 */
public static void delete(Node head, Node q) {
    //q不為空,q的下一個結點也不為空
    if (q != null && q.next != null) {
        //思路:把q的next的next指向q的next,
        //這樣之前q的next就被刪除了
        Node p = q.next;
        q.data = p.data;
        q.next = p.next;
        p = null;
    }
    //刪除最後一個節點
    if (q.next == null) {
        while (head != null) {
            //遍歷前面的連結串列,當該節點的next就是q的時候
            //然後把q設定成null
            if (head.next != null && head.next == q) {
                head.next = null;
                break;
            }
            head = head.next;
        }

    }
}

/**
 * 翻轉連結串列
 * 時間複雜度O(N)
 * 空間複雜度O(1)
 */
public static Node reversal(Node head) {
    Node pre = null;
    Node next = null;
    while (head != null) {
        next = head.next;
        head.next = pre;
        pre = head;
        head = next;
    }
    return pre;
}

/**
 * 當偶數個則取前面那個
 *
 * @return  連結串列中的中間節點
 */
public static Node getMid(Node head) {
    if (head == null) {
        return head;
    }
    Node fast = head;
    Node slow = head;
    while (fast.next != null && fast.next.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
}

測試程式碼

public static void main(String[] args) {

    Node node1 = new Node(1);
    Node node2 = new Node(2);
    Node node3 = new Node(3);
    Node node4 = new Node(4);

    node1.next = node2;
    node2.next = node3;
    node3.next = node4;
    node4.next = null;

    query(node1);
    Node newHead = new Node(6);
    insertHead(node1, newHead);
    Node node7 = new Node(7);
    insertTail(node4, node7);
    query(newHead);
    System.out.println(find(newHead, 3));
    Node node8 = new Node(8);
    insert(node3, node8);
    query(newHead);
    delete(newHead, node3);
    query(newHead);

    Node head= new Node(1);
    Node n2 = new Node(2);
    Node n3 = new Node(3);
    head.next = n2;
    n2.next = n3;
    n3.next = null;
    System.out.println(getMid(head).data);
    System.out.println();
    Node node = reversal(head);
    while (node != null) {
        System.out.print(node.data + " ");
        node = node.next;
    }
}

結果