web-dev-qa-db-ja.com

リンクリストの最後にアイテムを追加する

私は試験のために勉強しています、そしてこれは古いテストからの問題です:

次の宣言を持つリストヘッドを持つ単一リンクリストがあります。

_class Node {
    Object data;
    Node next;
    Node(Object d,Node n) {
        data = d;
        next = n;
    }
}
_

リストの最後にxを追加するメソッドvoid addLast(Node header, Object x)を記述します。

私が実際に次のようなものを持っていた場合、私は知っています:

_LinkedList someList = new LinkedList();
_

次のようにして、最後にアイテムを追加するだけです。

_list.addLast(x);
_

しかし、どうすればここでそれを行うことができますか?

5
John
class Node {
    Object data;
    Node next;
    Node(Object d,Node n) {
        data = d ;
        next = n ;
       }

   public static Node addLast(Node header, Object x) {
       // save the reference to the header so we can return it.
       Node ret = header;

       // check base case, header is null.
       if (header == null) {
           return new Node(x, null);
       }

       // loop until we find the end of the list
       while ((header.next != null)) {
           header = header.next;
       }

       // set the new node to the Object x, next will be null.
       header.next = new Node(x, null);
       return ret;
   }
}
11
therin

ループを使用してリンクリスト全体をナビゲートし、各ノードの「次の」値を確認する必要があります。最後のノードは、次の値がnullのノードになります。このノードの次の値を、入力データを使用して作成する新しいノードにするだけです。

node temp = first; // starts with the first node.

    while (temp.next != null)
    {
       temp = temp.next;
    }

temp.next = new Node(header, x);

それが基本的な考え方です。もちろん、これは擬似コードですが、実装するのに十分単純なはずです。

8
Benjamin S
public static Node insertNodeAtTail(Node head,Object data) {
               Node node = new Node(data);
                 node.next = null;
                if (head == null){
                    return node;
                }
                else{
                    Node temp = head;
                    while(temp.next != null){
                        temp = temp.next;
                    }
                    temp.next = node; 
                    return head;
                }        
    }

テールノードを追跡している場合は、リスト内のすべての要素をループする必要はありません。

新しいノードを指すようにテールを更新するだけです。

AddValueToListEnd(value) {
    var node = new Node(value);

    if(!this.head) {
        this.head = node;
    } else {
        this.tail.next = node;
    }

    this.tail = node;
}

平易な英語で:

  • 指定された値で新しいノードを作成し、tail = nullに設定します
  • リストが空の場合、ヘッドとテールの両方が新しいノードを指します
  • リストが空でない場合は、古いtail.nextを新しいノードに設定します
  • いずれの場合も、テールポインタを新しいノードになるように更新します
1
TomDane

これがリンクリストクラスの部分的な解決策です。実装の残りの部分はあなたに任せました。また、リンクリストの一部としてテールノードを追加するという良い提案も残しました。

ノードファイル:

public class Node 
{
    private Object data; 
    private Node next; 

    public Node(Object d) 
    { 
        data = d ;
        next = null;
    }

    public Object GetItem()
    {
        return data;
    }

    public Node GetNext()
    {
        return next;
    }

    public void SetNext(Node toAppend)
    {
        next = toAppend;
    }
}

そしてここにリンクリストファイルがあります:

public class LL
{
    private Node head;

    public LL()
    {
        head = null;
    }

    public void AddToEnd(String x)
    {
        Node current = head;

        // as you mentioned, this is the base case
        if(current == null) {
            head = new Node(x);
            head.SetNext(null);
        }

        // you should understand this part thoroughly :
        // this is the code that traverses the list.
        // the germane thing to see is that when the 
        // link to the next node is null, we are at the 
        // end of the list.
        else {
            while(current.GetNext() != null)
                current = current.GetNext();

            // add new node at the end
        Node toAppend = new Node(x);
            current.SetNext(toAppend);
        }
    }
}
1

nullへの次のポインタを持つリンクリストの最後の要素にループし、data = objectとnextpointer = nullを持つ新しいノードを指すように次のポインタを変更します

0
Ahmed Elmorsy

AddLast()内のwhileループはO(n)複雑であるため、addLast()には最適化が必要です。以下はLinkedListの実装です。ll.addLastx(i)を使用してコードを1回実行し、 ll.addLast(i)で再度実行すると、addLast()とaddLast()の処理時間に大きな違いがあることがわかります。

Node.Java

package in.datastructure.Java.LinkedList;

/**
* Created by abhishek.panda on 07/07/17.
*/
public final class Node {
    int data;
    Node next;

    Node (int data){
       this.data = data;
    }
    public String toString(){
      return this.data+"--"+ this.next;
    }
}

LinkedList.Java

package in.datastructure.Java.LinkedList;
import Java.util.ArrayList;
import Java.util.Date;

public class LinkedList {

    Node head;
    Node lastx;
    /**
     * @description To append node at end looping all nodes from head
     * @param data
     */
    public void addLast(int data){

        if(head == null){
            head = new Node(data);
            return;
        }
        Node last = head;
        while(last.next != null) {
            last = last.next;
        }
        last.next = new Node(data);
    }


    /**
     * @description This keep track on last node and append to it
     * @param data
     */
    public void addLastx(int data){

        if(head == null){
            head = new Node(data);
            lastx = head;
            return;
        }
        if(lastx.next == null){
            lastx.next = new Node(data);
            lastx = lastx.next;
        }

    }

    public String toString(){
        ArrayList<Integer> arrayList = new ArrayList<Integer>(10);
        Node current = head;
        while(current.next != null) {
            arrayList.add(current.data);
            current = current.next;
        }
        if(current.next == null) {
            arrayList.add(current.data);
        }
        return arrayList.toString();
    }


    public static void main(String[] args) {
        LinkedList ll = new LinkedList();
        /**
         * @description Checking the code optimization of append code
         */
        Date startTime = new Date();
        for (int i = 0 ; i < 100000 ; i++){
            ll.addLastx(i);
        }
        Date endTime = new Date();
        System.out.println("To total processing time : " + (endTime.getTime()-startTime.getTime()));
        System.out.println(ll.toString());
    }

}
0
Abhishek Panda

ここにヒントがあります。リンクリスト内のノードのグラフがあり、linkedList内の最初のノードであるheadへの参照を常に保持しています。
nextはリンクリスト内の次のノードを指しているため、nextがnullの場合、リストの最後になります。

0
crowne

上記のプログラムでは、NullPointerExceptionが発生する可能性があります。これは、linkedListの最後に要素を追加する簡単な方法です。

public class LinkedList {
    Node head;

    public static class Node{
        int data;
        Node next;

        Node(int item){
            data = item;
            next = null;
        }
    }
    public static void main(String args[]){
        LinkedList ll = new LinkedList();
        ll.head = new Node(1);
        Node second = new Node(2);
        Node third = new Node(3);
        Node fourth = new Node(4);

        ll.head.next = second;
        second.next = third;
        third.next = fourth;
        fourth.next = null;

        ll.printList();
        System.out.println("Add element 100 to the last");
        ll.addLast(100);
        ll.printList();
    }
    public void printList(){
        Node t = head;
        while(n != null){
            System.out.println(t.data);
            t = t.next;
        }

    }

    public void addLast(int item){
        Node new_item = new Node(item);
        if(head == null){
            head = new_item;
            return;
        }
        new_item.next = null;

        Node last = head;
        Node temp = null;
        while(last != null){
            if(last != null)
                temp = last;
            last = last.next;
        }   

        temp.next = new_item;   
        return;
    }
}
0
user7420004