0

私はJavaが初めてで、Linkedリストを実装しようとしています(この目的のためにリストクラスが存在することは知っていますが、最初からそれを行うことで、言語が内部でどのように機能するかを理解できます)

メイン メソッドでは、4 つのノードを宣言し、3 つのノードを初期化します。リンク リストのヘッド ノードは null に設定されます。パラメータ head と newNode を指定して add 関数を初めて呼び出すと、head が null になるため、head を初期化し、newNode の値を割り当てます。main メソッドでは、head オブジェクトに add メソッドから新しい値が設定されることを期待しています。しかし、頭はまだヌルです。

なぜこれが起こっているのか理解していただければ幸いです。

コードがきれいでない場合はお詫び申し上げます。どうもありがとうございました。

public class LinkedList
{
    public void add(Node newNode, Node head)
    {
        if(head == null) 
        {
            head = new Node(); 
            head = newNode;              
        }
        else 
        {
            Node temp = new Node(); 
            temp = head; 

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

    public void traverse(Node head)
    {
        Node temp = new Node(); 
        temp = head; 

        System.out.println("Linked List:: ");

        while(temp.next!=null);  
        {
           System.out.println(" "  + temp.data); 
            temp = temp.next;
        }
    }

    public static void main(String args[])
    {
        Node head = null;
        Node newNode = new Node(null, 5); 
        Node newNode2 = new Node(null, 15); 
        Node newNode3 = new Node(null,30); 

        LinkedList firstList = new LinkedList(); 

        firstList.add(newNode,head); 

       // Part that I don't understand
       // why is head still null here? 

        if(head==null)
        {
         System.out.println("true");
        }

        firstList.traverse(head); 
        firstList.add(newNode2,head); 
        firstList.traverse(head); 
        firstList.add(newNode3,head); 
        firstList.traverse(head); 

    }

}

public class Node
{
    public Node next; 
    public int data; 

    public Node(Node next, int data)
    {
        this.next = next; 
        this.data = data; 
    }

    public Node()
    {
        this.next = null; 
        this.data = 0; 
    }

}
4

5 に答える 5

2

Java メソッドの引数は値渡しです。

public void add(Node newNode, Node head)
{
    if(head == null) 
    {
        head = new Node(); 
        head = newNode;              
    }
    ...

上記はhead、 のスコープ内のローカル変数のみを変更しますaddheadのスコープ内のローカル変数への参照mainはできません。呼び出し元が新しい値を取得できるようにする場合は、おそらく値を返す必要があります。


正直に言うと、オブジェクト指向プログラミングの主要な原則は、カプセル化することです。headあなたのは、LinkedList理想的には内部で維持されるフィールドであるべきです。なぜ別パーツにする必要があるの?本当に分離したいのならhead、なぜ静的ではないtraverseのでしょうか? add設計を修正するようにしてください。ここでコードを書き直すことにしました。

final class List {

  private Node head;

  public void add(final Node node) {
    if (head == null) {
      head = new Node();
    }
    Node cur;
    for (cur = head; cur.next != null; cur = cur.next)
      ;
    cur.next = node;
  }

  public String toString() {
    final StringBuilder builder = new StringBuilder("Linked List::");
    for (Node cur = head.next; cur != null; cur = cur.next) {
      builder.append("\n ").append(cur.data);
    }
    return builder.toString();
  }
}

final class Node {

  int data;
  Node next;

  Node(final int data) {
    this.data = data;
  }

  Node() { }
}

...次に、テストします:

  private static Node[] nodesFor(final int... values) {
    int n = values.length;
    final Node[] nodes = new Node[n];
    while (n > 0) {
      nodes[--n] = new Node(values[n]);
    }
    return nodes;
  }

  public static void main(final String[] argv) {
    final List list = new List();
    for (final Node node : nodesFor(5, 15, 30)) {
      list.add(node);
      System.out.println(list);
    }
  }
于 2012-08-30T22:26:17.497 に答える
2

問題は「追加」機能内にあると思います。「head」の値を関数スコープ内で変更するだけで、外側では変更しません。Java がパラメーター値の受け渡しを処理する方法に関する有用な情報をここで見つけることができます。

Java での LinkedList の優れた実装は こちらです。

于 2012-08-30T23:07:35.810 に答える
1

Making "head" reference another node has no effect on the calling code (java passes references, which in java are the "values" of the addresses).

You need a permanent reference to the head, so make it a field of your class:

private Node head = new Node(); // the head of your Node tree

public void add(Node newNode, Node parent) {
    // add node to parent.
    // for some calls, the parent will be the head
}
于 2012-08-30T22:29:41.690 に答える
0
    firstList.add(newNode,head); 

   /*
    Part you should know is, head is a local variable pointing to null.
    Passing head as parameter doesn't make it feasible to alter this local variable.
    Your check is worthless.
    Make public Node add(Node newNode, Node head) and return head from there.
   */ 
    head=firstList.add(newNode,head);

    if(head==null)
    {
     System.out.println("true");
    }
于 2012-08-30T22:27:11.617 に答える
0

これは、リンクされたリストのより良い移植です。ご注意ください:

  1. _head はプライベート メンバーである必要があります
  2. ノードは内部メカニズムです。Node オブジェクトの代わりに add メソッドに data パラメータを与える必要があります
  3. 私はこれを書いた、シンプルですが、あなたのコード、実装に基づいています

    public class LinkedList{
    private Node _head;
    public void add(int data)
    {               
            //Understand this code! What happens if _head=null?                 
            _head=new Node(_head,data); 
            /*
                 //Use the following code for a "Normal" nodes-order
                 if(_head==null)
                    _head=new Node(null,data);
                 else{
                   Node temp=_head;
                   while( temp.next!=null)
                      temp=temp.next;            
                   temp.next=new Node(null,data); 
                 }
            */
    }
    public void traverse()
    {
        System.out.println("Linked List:: ");
        Node temp=_head;
        while(temp!=null){
                System.out.println(" "  + temp.data); 
                temp = temp.next;
        }
    }
    public LinkedList(){
        _head=null;         //null is our lists anchor
    }
    
    public static void main(String args[])
    {
        LinkedList firstList = new LinkedList(); 
    
        firstList.add(5); 
        firstList.traverse(); 
        firstList.add(15); 
        firstList.traverse(); 
        firstList.add(30); 
        firstList.traverse(); 
    
    }
    

    }

于 2012-08-30T23:09:43.670 に答える