我试图用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中,应该保持插入顺序。我如何更改此代码来执行此操作。我现在无法从不同的角度思考。
答案 0 :(得分:2)
尝试一步一步地分析问题。
我们假设您要在列表中添加以下数字序列 - 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()方法而言......我会把它作为练习留给你。不能只是放弃一切,现在可以吗? ;)
答案 1 :(得分:1)
试试这个。但是你需要检查一下在调用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;
}
}
}
答案 2 :(得分:0)
怎么样:
public void add(String data){
Node newNode = new Node(data);
newNode.next = currentNode.next;
currentNode.next = newNode;
}
答案 3 :(得分:0)
我想出了以下实现。
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;
}
}
它工作正常。
答案 4 :(得分:0)
大多数LinkedLists都是使用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
}
不应读取头部位置的物体。