单链接列表:删除方法

时间:2011-04-05 18:57:15

标签: c#

我正在用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();
    }
}

7 个答案:

答案 0 :(得分:4)

我会将'if the head of node node'拉出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;
        } 
    }
}

答案 1 :(得分:2)

你有一条你不需要的行:

            m_HeadNode = null;
            m_HeadNode = aCurrentNode.m_NextNode;

在将m_HeadNode设置为其他内容之前,您无需将其设置为null。

答案 2 :(得分: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;
    }

答案 3 :(得分: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)
        }
    }    
}

答案 4 :(得分:0)

只有一个局部变量。
你的代码中有一个错误,想象你有一个包含3个元素且data = 5的列表,并且你想删除5,你的代码将头存储在aCurrentNode中并启动循环。条件是真的,所以你把头移到下一个。但是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来检查头部,但是你需要一个if来设置头部。另一个技巧是检查下一个节点数据。这样你就不需要保留以前的节点了。

答案 5 :(得分: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;
    }

这会删除具有特定索引的元素,而不会删除特定的

答案 6 :(得分: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;
            }
        }