【问题标题】:reverse a linked list in a recursive function c#在递归函数c#中反转链表
【发布时间】:2013-07-27 00:30:48
【问题描述】:

我在尝试为我在 C# 中创建的 LinkedList 类编写反向递归方法时遇到问题。 LinkedList 中有 2 个指针,一个指向头部,另一个指向尾部:

public class Node
{
    public object data;
    public Node next;
    public Node(object Data)
    {
        this.data = Data;
    }
}

public class LinkedList
{
    Node head;
    Node tail;
    public void Add(Node n)
    {
        if (head == null)
        {
            head = n;
            tail = head;
        }
        else
        {
            tail.next = n;
            tail = tail.next;
        }
    }

现在,递归反向函数是这样的:

    public void reverse_recursive()
    {
        Node temp_head = head;
        if (temp_head == tail)
        {

            return;
        }

        while (temp_head != null)
        {
            if (temp_head.next == tail)
            {
                tail.next = temp_head;
                tail = temp_head;
                reverse_recursive();
            }
            temp_head = temp_head.next;
        }
    }

我有两个问题:首先,一个逻辑问题,我知道 head 在反向之后没有指向第一个节点。第二个问题是我可能对空指针做错了,所以程序崩溃了。

我也给你主程序:

class Program
{
    static void Main(string[] args)
    {
        LinkedList L = new LinkedList();
        L.Add(new Node("first"));
        L.Add(new Node("second"));
        L.Add(new Node("third"));
        L.Add(new Node("forth"));
        L.PrintNodes();
        L.reverse_recursive();
        L.PrintNodes();
        Console.ReadLine();
    }
}

感谢您的帮助!!

【问题讨论】:

  • 我可以问你为什么你从来没有奖励过一个问题吗?
  • 在帮助我只想检查之前,您需要使用自己的链表类吗?有一个内置类:msdn.microsoft.com/en-us/library/he2s3bh7.aspx
  • 您在while 中检查(temp_head != null),但在temp_head.next 内可能是null 所以if (temp_head.next == tail) 可能会导致违规。

标签: c# singly-linked-list


【解决方案1】:
public void Reverse()
{
    this.Reverse(this.head);
}

private void Reverse(Node node)
{
    if (node != null && node.next != null)
    {
        // Create temporary references to the nodes, 
        // because we will be overwriting the lists references.
        Node next = node.next;
        Node afterNext = node.next.next;
        Node currentHead = this.head;

        // Set the head to whatever node is next from the current node.
        this.head = next;

        // Reset the next node for the new head to be the previous head.
        this.head.next = currentHead;

        // Set the current nodes next node to be the previous next nodes next node :)
        node.next = afterNext;

        // Keep on trucking.
        this.Reverse(node);
    }
    else
    {
        this.tail = node;
    }
}

【讨论】:

    【解决方案2】:
            public void reverse()
            {
                reverse_recursive(tail);
    
                Node tmp = tail;
                tail = head;
                head = tmp;
            }
    
            public void reverse_recursive(Node endNode)
            {
                Node temp_head = head;
                if (temp_head == endNode)
                {
                    return;
                }
    
                while (temp_head != null)
                {
                    if (temp_head.next == endNode)
                    {
                        break;
                    }
                    temp_head = temp_head.next;
                }
    
                endNode.next = temp_head;
                temp_head.next = null;
                reverse_recursive(temp_head);
            }
    

    另见this

    【讨论】:

      【解决方案3】:

      这里有另一个选项。

      class Program{
          static void Main(string[] args)
          {
              LinkedList L = new LinkedList();
              L.Add(new Node("first"));
              L.Add(new Node("second"));
              L.Add(new Node("third"));
              L.Add(new Node("forth"));
              L.PrintNodes();
              L.reverse_recursive();
              Console.WriteLine("---------------------");
              L.PrintNodes();
              Console.ReadLine();
          }
      }
      
      public class Node
      {
          public object data;
          public Node next;
          public Node(object Data)
          {
              this.data = Data;
          }
      }
      
      public class LinkedList
      {
          Node head;
          Node tail;
          public void Add(Node n)
          {
              if (head == null)
              {
                  head = n;
                  tail = head;
              }
              else
              {
                  tail.next = n;
                  tail = tail.next;
              }
      
          }
      
          public void PrintNodes()
          {
              Node temp = head;
      
              while (temp != null)
              {
                  Console.WriteLine(temp.data);
                  temp = temp.next;
              }
          }
      
      
          private LinkedList p_reverse_recursive(Node first)
          {
              LinkedList ret;
              if (first.next == null)
              {
                  Node aux = createNode(first.data);
                  ret = new LinkedList();
                  ret.Add(aux);
                  return ret;
              }
              else
              {
                  ret = p_reverse_recursive(first.next);
                  ret.Add(createNode(first.data));
                  return ret;
              }
      
          }
      
          private Node createNode(Object data)
          {
              Node node = new Node(data);
              return node;
          }
      
          public void reverse_recursive()
          {
      
              if (head != null)
              {
                  LinkedList aux = p_reverse_recursive(head);
                  head = aux.head;
                  tail = aux.tail;
              }
      
      
          }
      }
      

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        第二个变种

        private void p_reverse_recursive2(Node node)
            {
                if (node != null)
                {
                    Node aux = node.next;
                    node.next = null;
                    p_reverse_recursive2(aux);
                    if (aux != null)
                        aux.next = node;
                }
        
            }
        
            public void reverse_recursive()
            {
        
                if (head != null)
                {               
                    Node aux = head;
                    head = tail;
                    tail = aux;
                    p_reverse_recursive2(tail);
                }
        
        
            }
        

        【讨论】:

          【解决方案5】:

          主题的变化...

          public Node Reverse(Node head)
          {
              if(head == null)
              {
                  return null;
              }
          
              Node reversedHead = null;
              ReverseHelper(head, out reversedHead);
              return reversedHead;
          }
          
          public Node ReverseHelper(Node n, out Node reversedHead)
          {
              if(n.Next == null)
              {
                  reversedHead = n;
                  return n;
              }
          
              var reversedTail = ReverseHelper(n.Next, out reversedHead);
              reversedTail.Next = n;
              n.Next = null;
              return n;       
              }   
          }
          

          【讨论】:

            【解决方案6】:

            我只是在玩类似的脑筋急转弯,唯一的区别是 LinkedList 类只有 head 的定义,而所有其余节点都链接在那里。所以这是我快速而肮脏的递归解决方案:

            public Node ReverseRecursive(Node root)
                    {
                        Node temp = root;
                        if (root.next == null)
                            return root;
                        else
                            root = ReverseRecursive(root.next);
                        temp.next = null;
                        Node tail = root.next;
                        if (tail == null)
                            root.next = temp;
                        else
                            while (tail != null)
                            {
                                if (tail.next == null)
                                {
                                    tail.next = temp;
                                    break;
                                }
                                else
                                    tail = tail.next;
                            }
                        return root;
                    }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-12-14
              • 1970-01-01
              • 2017-08-16
              • 2019-08-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多