【问题标题】:LinkedList Remove the node before the node indicatedLinkedList 删除指定节点之前的节点
【发布时间】:2015-03-29 06:43:49
【问题描述】:

我实现了 2 个方法,即 RemoveAfter 和 RemoveBefore,它们将在指示节点之前/之后删除节点。方法 Remove After 工作正常,但我不知道为什么 RemoveBefore 给我错误,因为 front 总是为空。

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Question7
{
    public class LinkedListNode
    {
        public LinkedListNode next = null;
        public int data;
        public LinkedListNode(int d) { data = d; }
        public void AppendToTail(int d)
        {
            LinkedListNode end = new LinkedListNode(d);
            LinkedListNode n = this;
            while (n.next != null) { n = n.next; }
            n.next = end;
        }
    }

    class Program
    {
        #region DeleteAFter
        public static bool DeleteAfter(LinkedListNode n)
        {
            if (n == null || n.next == null)
            {
                return false; // Failure
            }

            LinkedListNode next = n.next;
            n.next = next.next;
            return true;
        }
        #endregion

        static LinkedListNode front;
        #region DeleteBefore
        public static bool DeleteBefore(LinkedListNode n)
        {
            LinkedListNode prev = null;
            LinkedListNode curr = front;
            prev = curr;

            while(curr.data != n.data)
            {
                prev = curr;
                curr = curr.next;
            }
            prev.data = curr.data;
            prev.next = curr.next;
            return true;
        }

        #endregion

        static void PrintList(LinkedListNode list)
        {
            while (list != null)
            {
                Console.Write(list.data + "->");
                list = list.next;
            }
            Console.WriteLine("null");
        }
        static void Main(String[] args)
        {
            LinkedListNode myList = new LinkedListNode(5);
            myList.AppendToTail(6);
            myList.AppendToTail(7);
            myList.AppendToTail(8);
            // Now the list is 5->6->7->8

            Console.Write("Before deletion: ");
            PrintList(myList); // 5->6->7->8->null 

            LinkedListNode deletedNode = myList;

            int val = 7;

            while (deletedNode.data != val)
            {
                deletedNode = deletedNode.next;
            }

            Console.Write("After deletion: ");
            if (DeleteBefore(deletedNode))
                PrintList(myList); 
            Console.Read();
        }
    }
}

【问题讨论】:

  • 你在做什么?你期待什么输出?在DeleteBefore,列表中有两个元素,即7,8
  • 我正在实现 2 种方法,这些方法将在指定节点之前/之后删除节点。输出将是删除节点后的列表。
  • 所以当列表中有两个元素时,即7,8,并且您调用DeleteBefore,您要删除哪个节点?
  • 例如,我有一个列表:5-6-7-8。如果我调用 DeleteBefore(8) 它将删除节点 7
  • 您是否注意到 DeleteBefore 从不 测试 null 的任何内容?

标签: c# linked-list head


【解决方案1】:

因为您无法从一个节点访问其前一个节点,所以在DeleteBefore 上您必须从根目录开始再次遍历列表:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Question7
{
    public class LinkedListNode
    {
        public LinkedListNode next = null;
        public int data;
        public LinkedListNode(int d) { data = d; }
        public void AppendToTail(int d)
        {
            LinkedListNode end = new LinkedListNode(d);
            LinkedListNode n = this;
            while (n.next != null) { n = n.next; }
            n.next = end;
        }
    }

    class Program
    {
        #region DeleteAFter
        public static bool DeleteAfter(LinkedListNode n)
        {
            if (n == null || n.next == null)
            {
                return false; // Failure
            }

            LinkedListNode next = n.next;
            n.next = next.next;
            return true;
        }
        #endregion

        static LinkedListNode front;
        #region DeleteBefore
        public static bool DeleteBefore(LinkedListNode root, LinkedListNode n)
        {
            LinkedListNode prev = root;
            LinkedListNode curr = n;

            // we're iterating from the root, looking if the next node is the one we're looking for.
            while (prev.next != null && curr.data != prev.next.data)
            {
                prev = prev.next;
            }

            // if we found it
            if (prev.next != null && curr.data == prev.next.data)
            {
                // we're rewiring our list. we can also prev.next = curr.next;
                prev.next = prev.next.next;
                return true;
            }

            return false;
        }

        #endregion

        static void PrintList(LinkedListNode list)
        {
            while (list != null)
            {
                Console.Write(list.data + "->");
                list = list.next;
            }
            Console.WriteLine("null");
        }
        static void Main(String[] args)
        {
            LinkedListNode myList = new LinkedListNode(5);
            myList.AppendToTail(6);
            myList.AppendToTail(7);
            myList.AppendToTail(8);
            // Now the list is 5->6->7->8

            Console.Write("Before deletion: ");
            PrintList(myList); // 5->6->7->8->null 

            LinkedListNode deletedNode = myList;

            int val = 7;

            while (deletedNode.data != val)
            {
                deletedNode = deletedNode.next;
            }

            Console.Write("After deletion: ");
            if (DeleteBefore(myList, deletedNode))
                PrintList(myList);
            Console.Read();
        }
    }
}

【讨论】:

    【解决方案2】:

    您的front 变量始终为空。那么如果它始终为空,它有什么用?你正在与它进行比较,所以你得到null exception。 您可以在不使用 front 变量的情况下执行此操作。

         public static LinkedListNode DeleteBefore(LinkedListNode n,LinkedListNode currentList)
        {
            LinkedListNode prev = currentList;
            while (prev.data!=n.data)
            {
                prev = prev.next;
            }
    
            currentList = prev;
    
            return currentList;
        }
    
    
             LinkedListNode myList = new LinkedListNode(5);
            myList.AppendToTail(6);
            myList.AppendToTail(7);
            myList.AppendToTail(8);
            // Now the list is 5->6->7->8
    
            Console.Write("Before deletion: ");
            PrintList(myList); // 5->6->7->8->null 
    
            LinkedListNode deletedNode = myList;
    
            int val = 7;
    
            while (deletedNode.data != val)
            {
                deletedNode = deletedNode.next;
            }
    
            Console.Write("After deletion: ");
            PrintList(DeleteBefore(deletedNode,myList));
    
           }
    

    【讨论】:

      【解决方案3】:

      前面变量中的值始终为空。稍后您将 curr 分配给 front 并尝试访问无效的 curr.data。您需要在 curr = 'this' 的地方实现 DeleteBefore 函数,它应该从 main 调用 myList.DeleteBefore(deletedNode)

              public static bool DeleteBefore(LinkedListNode n)
          {
              LinkedListNode prev = null;
              LinkedListNode curr = this;
      
              while(curr != null)
              {
                  if(curr.next.data == n.data)
      //if the next node has the same data as n,
      // then curr node has to be deleted
                      {
                           prev.next = curr.next;
                           return true;
                       }
                  prev = curr;
                  curr = curr.next;
              }
              return false;
          }
      

      在main中,你调用这个函数如下:

      myList.DeleteBefore(deletedNode);
      

      【讨论】:

      • 你能告诉我如何更改那里的代码,因为我不太明白你在说什么。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-24
      • 2013-11-02
      • 2015-08-26
      • 2018-12-25
      • 2011-07-27
      • 2015-01-24
      相关资源
      最近更新 更多