[英]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是用head
和tail
。 元素將添加到鏈接列表的末尾,並從鏈接列表的開頭讀取。
例如:
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.