简体   繁体   English

带链表的泛型方法

[英]Generic Methods with Linked-list

Hi I'm trying to make these 2 methods work, but even though I tried pretty much everything I can think of, it's still not working.嗨,我正在尝试使这 2 种方法起作用,但是即使我尝试了几乎所有我能想到的方法,它仍然无法正常工作。 Please tell me how to fix it!请告诉我如何修复它!

void add(Anything value): Adds a node containing newValue to the end of the list. void add(Anything value):将包含 newValue 的节点添加到列表的末尾。
void addAfter(int index, Anything value): Adds a Node node containing newValue after the node of index index(assume index start in 0). void addAfter(int index,Anything value):在索引索引节点之后添加一个包含 newValue 的 Node 节点(假设索引从 0 开始)。

Here's my code: ( The methods above appear at the bottom )这是我的代码:(上面的方法出现在底部

public class Node<Anything>
{

private Anything data;
private Node next;

Node(Anything a, Node<Anything> n)
{
    data = a;
    next = n;
}

public Anything getData()
{ 
    return this.data;
}

public Anything setData(Anything newData)
{
    Anything oldData = this.data;
    this.data = newData;
    return oldData;
}

public void setNext(Node<Anything> newNext)
{
    this.next = newNext;
}

public Node<Anything> getNext()
{
    return this.next;
}
 }


------------------------------------------

 
public class CS2LinkedList<Anything>
{  

private Node<Anything> first;
private Node<Anything> last;

public CS2LinkedList()
{
    first = null;
}

public boolean isEmpty()
{
    return (first == null);
}

public void addFirst(Anything d)
{
     Node<Anything> temp = first;
     first = new Node<>(d,temp);
}


public void clear()
{
    first = null;
}

public boolean contains(Anything value)
{
    for (Node curr = first; curr != null; curr = curr.getNext())
    {
        if (value.equals(curr.getData())){
            return true;
        }
    }
    return false;
}


public String toString()
{
    StringBuilder result = new StringBuilder();  //String result = "";
    for (Node curr = first; curr != null; curr = curr.getNext())
        result.append(curr.getData() + "->");  //result = result + curr.data + "->";
    result.append("[null]");
    return result.toString();   //return result + "[null]";
}


public int size()
{   
    int size = 0;
    for (Node curr = first; curr != null; curr = curr.getNext()){
         size++;
         if (first==null){
                 size = 0;
            }
        }
        return size;
         }
    

public Anything getFirst()
{   
   
    if (first!=null){
        return first.getData();
    }
    else{
       System.out.println("Sorry, the list is empty.");
       return null;
    }
    
}

public Anything getLast()
{
    if (first!= null){
        
        for(Node curr = first; curr != null; curr = curr.getNext()){
            first = curr;
        }
        return first.getData();
        //FIX: list2's size decreases by 1 after executing list2.getLast()
    }
    else{
        System.out.println("Sorry, the list is empty.");
        return null;
    }
}

public void add(Anything value){
    if (first==null){
        first = new Node<>(value,first);
    }
    
    Node<Anything> next = new Node<>(value, first);
    first.setNext(null);
    last = next;
 }

public void addAfter(int index, Anything value)
{
    return;
}
 }

A bit long answer, tried to explain every bit of problem and give the solution.有点长的答案,试图解释每一点问题并给出解决方案。 Have patience!有耐心!

You're code is exactly doing what you have told it to do, adding new nodes in reverse .您的代码完全按照您的要求执行,在 reverse 中添加新节点。 It is adding the new node as the first and set the current first as new node's next while addFirst() is called.它将new node添加为第first new node ,并在调用addFirst()时将current first节点设置为新节点的next节点。

But with the current add() method you've mentioned, you'll always get a linked list not more than one element by calling the printing toString() method, although you have the list containing not more than two nodes.但是使用您提到的当前add()方法,您将始终通过调用printing toString()方法获得一个不超过one元素的链表,尽管您的列表包含不超过两个节点。 Let's look at your code to understand this:让我们看看你的代码来理解这一点:

public void add(Anything value){
    if (first==null){
        first = new Node<>(value,first);
    }
    
    Node<Anything> next = new Node<>(value, first);
    first.setNext(null);
    last = next;
}

So what you are doing is, you're checking whether the first is null, which means, whether the current list is empty.所以你正在做的是,你正在检查第first是否为空,这意味着当前列表是否为空。 If true then initialize first with new value (say "x" ) and it's next as current first , which is null .如果为truefirst使用新值(例如"x" )进行初始化,然后将其作为current first ,即null So we get [first(x)] -> [null] as our current list.所以我们得到[first(x)] -> [null]作为我们当前的列表。

Next you're initializing a next node with the value and first as it's next.接下来,您将使用该value初始化next节点,并且first是它的下next节点。 Then you are setting the next of first as null and assigning next to the last .然后您将first的 next 设置为null并在last next分配。 So far we've got:到目前为止,我们有:

[next(x)] -> [first(x)] -> [null]        //where last node is next(x)

Now if you want to add(y) , another next will be initialized with the current first as the next of this new node.现在,如果您想add(y) ,另一个next将使用当前first初始化为这个新节点的下一个。 Then again redundant making of null of the next of the first .的然后再次重复制造null了的next中的first And again assigning this new node to last .并再次将此新节点分配给last Now we've got:现在我们有:

[next(y) -> [first(x)] -> [null]

So, here we go!所以,我们开始! You are losing the current last by assigning the new node to the last , and this last will have the first as it's next, always, how many nodes you want to add, it follows the same path.通过将新节点分配给current last ,您正在丢失current lastlast ,并且这个last将具有第first作为它的下一个,始终,您要添加多少个节点,它遵循相同的路径。

Hence, you'll get a linked list of two elements, always, with this add() method.因此,您将始终使用此add()方法获得two元素的链表。

But why the toString() gives only [first(x)] -> [null] as linked list?但是为什么 toString() 只给出[first(x)] -> [null]作为链表?

Well, look at the toString() function, it starts from first , runs until first.next == null .好吧,看看toString()函数,它从first开始,一直运行到first.next == null And, you have first.next == null , always, if you add nodes with this add() method.而且,如果您使用此add()方法添加节点,则始终具有first.next == null Therefore, such behavior of the toString() .因此, toString()这种行为。

What's the solution?解决办法是什么?

Set both of the first and last of the linked list in the constructor as null during the initialization.初始化时将构造函数中链表的firstlast都设置为空。 In the add() method, initialize the first for the first time with the value and last .add()方法中,第一次用valuelast初始化first And assign it to the last .并将其分配给last . return after that as we are done adding the first node.在我们完成添加第一个节点之后return Remove the first.setNext(null) statement, initialize the new node with value and null .删除first.setNext(null)语句,用 value 和null初始化new node Make the next of the current last as new node .current lastnext current last作为new node and assign the new node as the last.并将新节点分配为最后一个。 Here is the code:这是代码:

public void add(Anything value) {
    if (first == null) {
        first = new Node<>(value, last);
        last = first;
        return;
    }

    Node<Anything> next = new Node<>(value, null);
    last.setNext(next);
    last = next;
}

Now if you print the toString() , you'll get:现在如果你打印toString() ,你会得到:

node1->node2->node3->[null]

Hope you got your answer and desired solution!希望你得到你的答案和想要的解决方案!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM