簡體   English   中英

Java中的自定義LinkedList,其插入順序保持不變

[英]Custom LinkedList in Java with a maintained order of insertion

我試圖用Java實現一個鏈表。 我想出了以下簡單的實現

public class Node{
  public String data;
  public Node next;
  public Node(String data){
     this.data = data  
  }
}

public class LinkedLst{
  public Node currentNode;

  public void add(String data){
    Node newNode = new Node(data);
    newNode.next = currentNode;
    currentNode = newNode;
  }
  public Node remove(){
    Node temp = currentNode;
    currentNode = currentNode.next;
    return temp;
  }
  public void printList(){
    Node temp = currentNode;
    while(temp!=null){
      System.out.println(temp.data + ",");
      temp = temp.next;
    }
  }
}

但是我在這里看到的一個明顯問題是,由於我的設計缺陷,插入順序被顛倒了。 但是在LinkedList中,插入順序應保持不變。 我將如何更改此代碼來做到這一點。 我現在無法從另一個角度思考。

嘗試一次分析問題。

讓我們假設您想將以下數字序列添加到列表中-1,2,3,4,5。究竟發生了什么?

LinkedList類的對象中只有一個字段(currentNode)。 讓我們嘗試像這樣可視化它;

LinkedList
  currentNode = null

至此,列表中沒有任何數據。 現在,我們插入第一個節點(我正在分配字母來表示它們)。

LinkedList
  currentNode = A

列表序列本身看起來像這樣;

null <- A(value = 1)

現在,將第二個數據添加到列表中。 注意會發生什么;

LinkedList
  currentNode = B

列表序列變為:

null <- A(value = 1) <- B(value = 2)

還有其他一些元素,您會遇到這種情況

LinkedList
  currentNode = E

順序是

null <- A(value = 1) <- B(value = 2) <- C(value = 3) <- D(value = 4) <- E(value = 5)

在這種情況下,您可以遍歷列表的唯一順序是什么? 相反。 為什么? 因為您僅存儲列表的LAST(或尾部)節點。 如果要檢索原始訂單,則需要更改邏輯,以便存儲列表的HEAD(而不是尾部)。 首先,讓我們按照以下步驟重命名班級中的字段;

public class LinkedList {
    public Node HEAD;
}

我們需要解決的下一個更改是您的add()方法。 考慮最終目標。 您想如何在列表中存儲內容? 我懷疑這就是您要找的東西;

A(value = 1) -> B(value = 2) -> C(value = 3) -> D(value = 4) -> E(value = 5) -> null

如果您在上面的列表中有第一個元素(HEAD = A),您將如何向列表中添加新元素? 您將需要遍歷列表,直到到達最后一個節點,然后在其中插入新值。 這樣您的功能就會變成;

public void add(String data) {
    Node newNode = new Node(data);
    // check if HEAD is empty or not
    if (HEAD == null) {
        HEAD = newNode;
        return;
    }
    Node temp = HEAD;
    while(temp.next != null) {
        temp = temp.next;
    }
    // we must be at the end of the list now.
    // add the next element in here.
    temp.next = newNode;
}

為了驗證這一點,需要對打印功能進行一些小的更改(使用HEAD代替currentNode)。 最后一堂課看起來像這樣;

public class LinkedList {
    public Node HEAD;

    public void add(String data) {
        Node newNode = new Node(data);
        // check if HEAD is empty or not
        if (HEAD == null) {
            HEAD = newNode;
            return;
        }
        Node temp = HEAD;
        while(temp.next != null) {
            temp = temp.next;
        }
        // we must be at the end of the list now.
        // add the next element in here.
        temp.next = newNode;
    }

    public void printList() {
        Node temp = HEAD;
        while(temp != null) {
            System.out.print(temp.data + " -> " );
            temp = temp.next;
        }
    }
}

至於remove()方法……我將作為練習留給您。 不能只是放棄一切,現在可以嗎? ;)

嘗試這個。 但是再次,您需要檢查在調用remove的情況下,不添加任何元素的情況,在代碼中可能存在NPE的情況下,您需要處理這些情況以及線程安全性和列表性能:

package com.test.java;

import java.util.concurrent.atomic.AtomicInteger;

class Node<T> {
    T data;
    Node next;  
    int index;
    static AtomicInteger position = new AtomicInteger();
    public Node(T data){
        this.data = data;
        this.index = position.incrementAndGet(); 
    }
    @Override
    public String toString() {      
        return data.toString();
    }
}

public class LinkedLst<T> {
    private Node currentNode;

    public void add(T data){
        Node newNode = new Node(data);
        newNode.next = currentNode;
        currentNode = newNode;
    }

    public Node remove(){
        Node temp = currentNode;
        currentNode = currentNode.next;
        return temp;
    }

    public Node get(int index) {
        Node temp = currentNode;
        while(temp!=null){
            if(index == temp.index) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }

    public void printList(){
        Node temp = currentNode;
        while(temp!=null){
            System.out.println(temp.data + ",");
            temp = temp.next;
        }
    }
}

關於什么:

public void add(String data){
  Node newNode = new Node(data);
  newNode.next = currentNode.next;
  currentNode.next = newNode;
} 

我想出了以下實現。

public class LinkedLst {
    public Node head;
    public Node prev;
    public Node last;

    public void add(String data) {
        Node newNode = new Node(data);
        if(head == null){
            head = newNode;
            prev = newNode;
            last = newNode;
            return;
        }else if(head == last){
            prev.next = newNode;
            last = newNode;
            return;
        }
        prev = prev.next;
        prev.next = newNode;
        last = newNode;
    }

    public void fwdPrintList() {
       Node temp = head;
       while (temp!=null){
           System.out.println(temp.data);
           temp = temp.next;
       }
    }

    public Node remove(){
        if(isEmpty()){
            System.out.println("List is Empty");
            return head;
        }
        Node temp = head;
        head = head.next;
        return temp;
    }
    public boolean contains(String data) {
        Node temp = head;
        while (temp!=null){
            if (temp.data.equals(data)) {
                return true;
            }
        temp = temp.next;
        }
        return false;
    }

    public boolean isEmpty(){
        if(head==null){
            return true;
        }
        return false;
    }
}

而且效果很好。

大多數LinkedList是用headtail 元素將添加到鏈接列表的末尾,並從鏈接列表的開頭讀取。

例如:

private Node head = new Node(null);
private Node tail = head;

public void add(Object o) {
    Node node = new Node(o);
    tail.next = node;
    tail = node; // Swing tail to the added node
}

public Object peek() {
    if (head != tail)
        return head.next.value; // Value of the next node
    return null; // Empty
}

public Object poll() {
    if (head != tail) {
        Object o = head.next.value;
        head = head.next;
        return o;
    }
    return null; // Empty
}

頭部位置的物體不應被讀取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM