2011-04-05 22 views
0

我寫在C#中的單鏈表,能否請你建議我,如果有什麼辦法可以寫出更好的去除方法比我有:單鏈表:去除方法

using System; 

class Node 
{ 
    public int data = int.MinValue; 
    public Node m_NextNode; 

    public Node(int data_in) 
    { 
     data = data_in; 
    } 

    public Node() 
    { 
    } 
} 

class LinkedList 
{ 
    private Node m_HeadNode; 

    public void InsertData(int data) 
    { 
     Node aCurrentNode = m_HeadNode; 
     if(m_HeadNode == null) 
     { 
      m_HeadNode = new Node(); 
      m_HeadNode.data = data; 
     } 
     else 
     { 
      while(aCurrentNode.m_NextNode != null) 
       aCurrentNode = aCurrentNode.m_NextNode; 

      aCurrentNode.m_NextNode = new Node(); 
      aCurrentNode.m_NextNode.data = data; 
     } 
    } 

    public void DisplayData() 
    { 
     Node aCurrentNode = m_HeadNode; 

     while (aCurrentNode != null) 
     { 
      Console.WriteLine("the value is {0}", aCurrentNode.data); 
      aCurrentNode = aCurrentNode.m_NextNode; 
     }  
    } 

    public void RemoveData(int data) 
    { 
     Node aCurrentNode = m_HeadNode; 

     while (aCurrentNode != null) 
     { 
      //if the data is present in head 
      //remove the head and reset the head 
      if (m_HeadNode.data == data) 
      { 
       m_HeadNode = null; 
       m_HeadNode = aCurrentNode.m_NextNode; 
      } 
      else 
      { 
       //else save the previous node 
       Node previousNode = aCurrentNode; 
       if (aCurrentNode != null) 
       { 
        //store the current node 
        Node NextNode = aCurrentNode.m_NextNode; 
        if (NextNode != null) 
        { 
         //store the next node 
         Node tempNode = NextNode.m_NextNode; 

         if (NextNode.data == data) 
         { 
          previousNode.m_NextNode = tempNode; 
          NextNode = null; 
         } 
        } 

        aCurrentNode = aCurrentNode.m_NextNode; 
       } 
      }    
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     LinkedList aLinkedList = new LinkedList(); 
     aLinkedList.InsertData(10); 
     aLinkedList.InsertData(20); 
     aLinkedList.InsertData(30); 
     aLinkedList.InsertData(40); 
     aLinkedList.DisplayData(); 

     aLinkedList.RemoveData(10); 
     aLinkedList.RemoveData(40); 

     aLinkedList.RemoveData(20); 
     aLinkedList.RemoveData(30); 

     aLinkedList.DisplayData(); 

     Console.Read(); 
    } 
} 
+0

你的代碼塊真的被破壞了,但這會有幫助嗎? http://stackoverflow.com/questions/1432818/remove-node-from-single-linked-list – LeRoy 2011-04-05 19:03:14

+1

你是什麼意思'更好'?更可讀,更高性能,更少代碼等? – Tejs 2011-04-05 19:09:21

+0

這只是一個編程練習? C#[已經有](http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx)內置的類型安全的雙向鏈表。 – Powerlord 2011-04-05 19:30:30

回答

2

你有行,你並不需要:

  m_HeadNode = null; 
      m_HeadNode = aCurrentNode.m_NextNode; 

你不需要m_HeadNode將它設置爲別的東西之前設置爲null。

+0

else的部分,我用三個節點去除數據;首先記住前一個節點,然後從前一個節點取當前節點從當前我得到的下一個節點,一旦數據匹配,我刪除當前節點並建立之前和當前節點之間的鏈接,有沒有更好的方法方式實現相同的 – Raghav 2011-04-05 19:13:45

4

我會'如果刪除頭節點'的while循環,並使while循環更簡單。只需跟蹤當前和之前的節點,並在找到要刪除的節點時切換參考。

public void RemoveData(int data) 
{ 
    if (m_HeadNode == null) 
     return; 

    if (m_HeadNode.data == data) 
    { 
     m_HeadNode = m_HeadNode.m_NextNode; 
    } 
    else 
    { 
     Node previous = m_HeadNode; 
     Node current = m_HeadNode.m_NextNode; 

     while (current != null) 
     { 
      if (current.data == data) 
      { 
       // If we're removing the last entry in the list, current.Next 
       // will be null. That's OK, because setting previous.Next to 
       // null is the proper way to set the end of the list. 
       previous.m_NextNode = current.m_NextNode; 
       break; 
      } 

      previous = current; 
      current = current.m_NextNode; 
     } 
    } 
} 

RemoveData是否應該從列表或所有實例中刪除該整數的一個實例?前面的方法只刪除第一個,這是一個刪除所有這些。

public void RemoveAllData(int data) 
{ 
    while (m_HeadNode != null && m_HeadNode.data == data) 
    { 
     m_HeadNode = m_HeadNode.m_NextNode; 
    } 

    if(m_HeadNode != null) 
    { 
     Node previous = m_HeadNode; 
     Node current = m_HeadNode.m_NextNode; 

     while (current != null) 
     { 
      if (current.data == data) 
      { 
       // If we're removing the last entry in the list, current.Next 
       // will be null. That's OK, because setting previous.Next to 
       // null is the proper way to set the end of the list. 
       previous.m_NextNode = current.m_NextNode; 
       // If we remove the current node, then we don't need to move 
       // forward in the list. The reference to previous.Next, below, 
       // will now point one element forward than it did before. 
      } 
      else 
      { 
       // Only move forward in the list if we actually need to, 
       // if we didn't remove an item. 
       previous = current; 
      } 

      current = previous.m_NextNode; 
     } 
    } 
} 
0
public void RemoveData(int data) 
{ 
    if(null == m_HeadNode) return; 
    if(m_HeadNode.data == data) 
    { 
     // remove first node 
    } 
    else 
    { 
     Node current = m_HeadNode; 
     while((null != current.m_NextNode) && (current.m_NextNode.data != data)) 
      current = current.m_NextNode; 
     if(null != current.m_NextNode) 
     { 
      // do remove node (since this sounds like homework, I'll leave that to you) 
     } 
    }  
} 
0

只有一個局部變量。
在你的代碼中存在一個錯誤,想象你有一個列表,其中有3個元素,其中data = 5,並且你想刪除5,你的代碼將頭部存儲在currentNode中並啓動循環。那裏的條件是真的,所以你把頭移到下一個。但是aCurrentNode沒有更新,所以在下一次迭代時它指向前一個Head並且aCurrentNode.m_NextNod將會是你當前的Head,因此你得到了一個永無止境的循環!

public void Remove(int data) 
    { 
     for(var cur = new Node {Next = Head}; cur.Next != null; cur = cur.Next) 
     { 
     if (cur.Next.Data != data) continue; 
     if (cur.Next == Head) 
      Head = Head.Next; 
     else 
      cur.Next = cur.Next.Next; 
     } 
    } 

讓你循環更簡單的一個訣竅是從一個指向頭部的假節點開始。這樣你不需要放置一個If來檢查頭部,但是你需要一個如果設置頭部。另一個技巧是檢查下一個節點的數據。這樣你就不需要保留以前的節點。

1
public bool RemoveNode(int data) { 
     Node prev = null; 
     for (Node node = head; node != null; node = node.next) { 
      if (node.data == data) { 
       if (prev == null) head = node.next; 
       else prev.next = node.next; 
       return true; 
      } 
      prev = node; 
     } 
     return false; 
    } 
+0

你並不真的需要返回,他的實現將刪除所有的數據發生。 – Mehran 2011-04-05 20:46:57

0
public SLElement Remove(int index) 
    { 
     SLElement prev = _root; 
     if (prev == null) return null; 
     SLElement curr = _root._next; 
     for (int i = 1; i < index; i++) 
     { 
     if (curr == null) return null; 
     prev = curr; 
     curr = curr._next; 
     } 
     prev._next = curr._next; 
     curr._next = null; 
     return curr; 
    } 

這將刪除該元素與特定索引,沒有與特定

0

使真正簡單。請按照link。以下是從單個鏈接列表中刪除項目的代碼片段。

public void DeleteNode(int nodeIndex) 
     { 
      int indexCounter = 0; 
      Node TempNode = StartNode; 
      Node PreviousNode = null; 
      while (TempNode.AddressHolder != null) 
      { 
       if (indexCounter == nodeIndex) 
       { 
        PreviousNode.AddressHolder = TempNode.AddressHolder; 
        break; 
       } 
       indexCounter++; 
       PreviousNode = TempNode; 
       TempNode = TempNode.AddressHolder; 
      } 
     }