2017-02-20 5 views
0

C#を使用して単独リンクリストを実装しました。誰でも次のコードを見て、私が間違っている場所を提案してもらえますか?C#を使用した単独リンクリストの実装 - RemoveLastメソッド

public int RemoveLast() 
{ 
    if (Head != null) 
    { 
     var curNode = Head; 

     while (curNode.Next != null) 
     { 
       curNode = curNode.Next; 
     } 

     var lastNodeValue = curNode.Value; 

     curNode = null; 
     Size--; 
     return lastNodeValue; 
    } 

    return -1; 
} 

この機能では、最後のノードは削除されません。私は何が間違っているのか理解できません。 whileループが終了すると、次のノードがnullのcurNodeにnodeの参照があります。これが最後のノードであることを意味します。最後に、このノードをnullに設定しています。しかし、私は表示機能を使用します。最後のノードも表示されます。これは、最後のノードを削除していません。あなたは前のノード上のcurNode.Next値がnullにする必要があり

public string Display() 
    { 
     if (Head == null) 
     { 
      return string.Empty; 
     } 

     var curNode = Head; 
     var builder = new StringBuilder(); 

     while (curNode.Next != null) 
     { 
      builder.Append($"{curNode.Value} "); 
      curNode = curNode.Next; 
     } 

     builder.Append($"{curNode.Value} "); 

     return builder.ToString(); 
    } 
+1

あなたはあなたのcurrNodeを消去しています。リストから何も削除されません。期待される賞賛。最後のノードを削除するには、*最後の* Nodeの 'Next'プロパティをクリアする必要があります。 – Fildor

+3

'.Next'プロパティをnullに変更していません。ローカル参照をnullに変更するだけです。 –

+0

私の推測では、curNodeはリスト要素のローカルコピーです。実際のリスト要素ではありません。 curNodeをvarにすると、その型が曖昧になります。あなたは、明示的なタイピングによってそれを報復するべきです。 Tahtはまさにvarを使わないべきケースです。 – Christopher

答えて

1
[x] -> [x] -> [x] -> null 
      ^
       curNode (becomes null) 
     ^
      this reference still exists 

curNode = nullを実行すると、リスト内の参照は変更されません。 curNode変数は変更されたに過ぎず、操作前の最後の要素を指しており、nullになります。

最後の前のノードへの参照を保持し、常に試してみてください:

public int RemoveLast() 
{ 
    if (Head != null) 
    { 
     var curNode = Head; 
     // Corner case when there is only one node in the list 
     if (Head.Next == null) 
     { 
      Head = null; 
      Size--; 
      return curNode.value; 
     } 

     var beforeLastNode = curNode; 
     curNode = curNode.Next; 
     while (curNode.Next != null) 
     { 
      beforeLastNode = curNode; 
      curNode = curNode.Next; 
     } 

     var lastNodeValue = curNode.Value; 

     beforeLastNode.Next = null; 
     Size--; 
     return lastNodeValue; 
    } 

    return -1; 
} 
0

は、ここに私の表示機能です。 'curNode'はローカル変数です。nullに設定すると、GCライフを延長すること以外は何もしません。

あなたが最後に - しかし、一つのノードに移動して、nullにその Nextを変更する必要が
public int RemoveLast() 
{ 
    if (Head != null) 
    { 
     var curNode = Head; 
     var previousNode = null; 

     while (curNode.Next != null) 
     { 
       previousNode = curNode; 
       curNode = curNode.Next; 
     } 

     var lastNodeValue = curNode.Value; 

     if (previousNode == null) 
      Head = null; 
     else 
      previousNode.Next = null; 
     Size--; 
     return lastNodeValue; 
    } 

    return -1; 
} 
+0

ここでも:サイズ== 1の場合はどうなりますか? – Fildor

+1

@Fildorありがとう。 –

2

public int RemoveLast() 
{ 
    if (Head != null) 
    { 
     var curNode = Head; 

     while (curNode.Next?.Next != null) 
     { 
      curNode = curNode.Next; 
     } 

     var lastNodeValue = curNode.Next?.Value ?? -1; 
     curNode.Next = null; 
     Size--; 
     return lastNodeValue; 
    } 

    return -1; 
} 

注意あなたもその場合にのみHeadはnullに設定したい場合は、そのノードは、その後、あなたはそうのようなことを行うことができます。

public int RemoveLast() 
{ 
    if (Head != null) 
    { 
     var curNode = Head; 

     while (curNode.Next?.Next != null) 
     { 
      curNode = curNode.Next; 
     } 

     int lastNodeValue; 

     if (Head.Next == null) 
     { 
      lastNodeValue = Head.Value; 
      Head = null; 
     } 
     else 
     { 
      lastNodeValue = curNode.Next?.Value ?? -1; 
     } 
     curNode.Next = null; 
     Size--; 
     return lastNodeValue; 
    } 

    return -1; 
} 

私も言わなければならない、このHeadプロパティは少し怪しげに見える - それはおそらく別のクラスに属している必要があります。

+0

サイズ= 1の場合、ヘッドノードは削除されません。 – Fildor

+1

@Fildorはい、この問題はこの奇妙な 'Head'プロパティです。私たちはそれが何であるか分からないので、実際には対処できません。だから「頭」は変更されません。しかし、必要があれば何をすべきかを示す例を追加します。 –

+0

編集後:ヘッドはまだ削除されていません。私はそれが最初のノードへのリストのreferecneだと思うが、あなたは正しい、OPは私達に知らせるべきである。私はしばらくしてからチェックを追加します: 'if(curNode == Head)Head = null;' – Fildor

0

いい連中は、あなたの助けの後、私はすべての要件を満たし、このメソッドを書き換えてきたし、1つのノードしかない場合はヘッドノードnullに設定リンクされたリストで。だからここに行く:

public int RemoveLast() 
    { 
     if (HeadNode != null) 
     { 
      var currNode = HeadNode; 
      var prevNode = HeadNode; 

      if (HeadNode.Next == null) 
      { 
       HeadNode = null; 
       Size--; 
       return currNode.Value; 
      } 

      while (currNode.Next != null) 
      { 
       prevNode = currNode; 
       currNode = currNode.Next; 
      } 

      prevNode.Next = null; 
      Size--; 
      return currNode.Value; 
     } 

     return -1; 
    } 

このスレッドに貢献してくれてありがとうございました。ハッピーコーディング:)

関連する問題