在递归函数c#中反转链表

时间:2013-07-26 16:24:20

标签: c# singly-linked-list

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

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

我也给你主程序:

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

感谢您的帮助!!

5 个答案:

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

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

另见this

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


    }
}

希望有所帮助

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


    }

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