3

我在尝试为我在 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();
    }
}

感谢您的帮助!!

4

6 回答 6

3
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;
    }
}
于 2013-07-26T16:40:51.660 回答
0

这里的另一个选择。

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;
        }


    }
}

希望能帮助到你

于 2013-07-26T16:58:58.837 回答
0

第二种变体

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);
        }


    }
于 2013-07-26T17:33:17.020 回答
0
        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);
        }

另请参阅

于 2013-07-26T16:39:22.117 回答
0

主题变奏...

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;       
    }   
}
于 2014-05-30T04:56:13.267 回答
0

我只是在玩类似的脑筋急转弯,唯一的区别是 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;
        }
于 2016-08-15T14:52:50.823 回答