使用和不使用递归来反转单链表

发布于 2024-08-18 03:42:47 字数 105 浏览 4 评论 0原文

我是数据结构的新手,我知道这是一个很常见的问题。但我知道 .NET 中的 LinkedList 是双向链接的,那么我将如何在 C# 中为单链表编写代码。

有人可以写一下示例代码吗?

I am new to data structures, and I know this is a very common question to ask. But I know LinkedList in .NET is doubly-linked, so how I will write code for a singly-linked list in C#.

Could someone please write sample code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

乞讨 2024-08-25 03:42:47

这里就用到了递归。

private void Reverse(Item item)
    {
        if (item == null || item.Next == null) //if head is null or we are at the tail
        {
            this.Head = item; //we are at the tail or empty list, set the new head to the tail
            return;
        }

        Reverse(item.Next);

        var nextItem = item.Next; //get the next item out, dealing with references don't want to override it
        item.Next = null;         //once you get the next item out, you can delete the *reference* i.e. link to it
        nextItem.Next = item;     //set the item you got out link to next item to the current item i.e. reverse it
    }

Here it is using recursion.

private void Reverse(Item item)
    {
        if (item == null || item.Next == null) //if head is null or we are at the tail
        {
            this.Head = item; //we are at the tail or empty list, set the new head to the tail
            return;
        }

        Reverse(item.Next);

        var nextItem = item.Next; //get the next item out, dealing with references don't want to override it
        item.Next = null;         //once you get the next item out, you can delete the *reference* i.e. link to it
        nextItem.Next = item;     //set the item you got out link to next item to the current item i.e. reverse it
    }
可是我不能没有你 2024-08-25 03:42:47

使用循环(当前元素:currentNode,在循环外初始化的变量:previousNode,nextNode)

Set nextNode = currentNode.NextNode
Set currentNode.NextNode = previousNode
Set previousNode = currentNode
Set currentNode = nextNode
continue with loop

Use loop (current element: currentNode, variables initialzied outside loop: previousNode, nextNode)

Set nextNode = currentNode.NextNode
Set currentNode.NextNode = previousNode
Set previousNode = currentNode
Set currentNode = nextNode
continue with loop
丿*梦醉红颜 2024-08-25 03:42:47
reversed_list = new
for all node in the original list
   insert the node to the head of reversed_list
reversed_list = new
for all node in the original list
   insert the node to the head of reversed_list
猛虎独行 2024-08-25 03:42:47

由于这可能是家庭作业,因此我将以一种可能非常令人困惑的方式来陈述这一点,以免完成所有工作。希望我的尝试不会让事情变得更加混乱(这是很有可能的)。

当您拥有对列表中节点(例如第一个节点)的引用时,您还拥有对其后面的节点的引用。您只需使以下节点引用当前节点,同时保留有关以下节点(及其先前状态)的足够信息即可为其执行类似的工作。现在唯一棘手的部分是处理边界条件(列表的开头和结尾)。

Since this is likely homework, I'm going to state this in a way that might be pretty confusing so as not to do all the work. Hopefully my attempt doesn't just make things more confusing (which is highly possible).

When you have a reference to a node in the list (say the first node), you also have a reference to the node that follows it. You just need to make the following node refer to your current node while keeping enough information around about the following node (and its previous state) to perform similar work for it. Now the only tricky parts are dealing with the boundary conditions (the start and the end of the list).

可是我不能没有你 2024-08-25 03:42:47
//Have tried the Iterative approach as below, feel free to comment / optimize 

package com.test;


public class ReverseSinglyLinkedList {


public ReverseSinglyLinkedList() {
    // TODO Auto-generated constructor stub
}
public Node ReverseList(Node n)
{

    Node head =  n; 
    Node current = n; 
    Node firstNodeBeforeReverse = n;  // keep track of origional FirstNode

    while(true) 
    {

        Node temp = current; 
         // keep track of currentHead in LinkedList "n", for continued access to unprocessed List
        current = current.next; 
        temp.next = head;
          // keep track of head of Reversed List that we will return post the processing is over 
        head = temp;   

        if(current.next == null)
        {

            temp = current;
            current.next = head;
            head = temp;        
                            // Set the original FirstNode to NULL
            firstNodeBeforeReverse.next = null; 

            break;
        }
    } 

    return head;

}

public void printLinkList(Node n)
{

    while(true)
    {
        System.out.print(n.data + " ");
        n = n.next;
        if(n.next ==null)
        {
            System.out.print(n.data + " ");
            break;
        }

    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub

    // TEST THE PROGRAM: crate a node List first to reverse it
    Node n = new Node(1);
    n.next = new Node(2);
    n.next.next = new Node(3);
    n.next.next.next = new Node(4);
    n.next.next.next.next = new Node(5);
    n.next.next.next.next.next = new Node(6);

    ReverseSinglyLinkedList r = new ReverseSinglyLinkedList();
    System.out.println("Input Linked List : ");  
    r.printLinkList(n);

    Node rsList = r.ReverseList(n);

    System.out.println("\n Reversed Linked List : ");
    r.printLinkList(rsList);



}

}
//Have tried the Iterative approach as below, feel free to comment / optimize 

package com.test;


public class ReverseSinglyLinkedList {


public ReverseSinglyLinkedList() {
    // TODO Auto-generated constructor stub
}
public Node ReverseList(Node n)
{

    Node head =  n; 
    Node current = n; 
    Node firstNodeBeforeReverse = n;  // keep track of origional FirstNode

    while(true) 
    {

        Node temp = current; 
         // keep track of currentHead in LinkedList "n", for continued access to unprocessed List
        current = current.next; 
        temp.next = head;
          // keep track of head of Reversed List that we will return post the processing is over 
        head = temp;   

        if(current.next == null)
        {

            temp = current;
            current.next = head;
            head = temp;        
                            // Set the original FirstNode to NULL
            firstNodeBeforeReverse.next = null; 

            break;
        }
    } 

    return head;

}

public void printLinkList(Node n)
{

    while(true)
    {
        System.out.print(n.data + " ");
        n = n.next;
        if(n.next ==null)
        {
            System.out.print(n.data + " ");
            break;
        }

    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub

    // TEST THE PROGRAM: crate a node List first to reverse it
    Node n = new Node(1);
    n.next = new Node(2);
    n.next.next = new Node(3);
    n.next.next.next = new Node(4);
    n.next.next.next.next = new Node(5);
    n.next.next.next.next.next = new Node(6);

    ReverseSinglyLinkedList r = new ReverseSinglyLinkedList();
    System.out.println("Input Linked List : ");  
    r.printLinkList(n);

    Node rsList = r.ReverseList(n);

    System.out.println("\n Reversed Linked List : ");
    r.printLinkList(rsList);



}

}
反差帅 2024-08-25 03:42:47

这是 .net (C#) 中链接的反转迭代和递归
(请注意,链表同时维护第一个和最后一个指针,以便我可以在 O(1) 中追加到末尾或在头部插入 - 不必这样做。我只是按上面定义了我的链表行为)

public void ReverseIterative()
        {
            if(null == first)
            {
                return;
            }
            if(null == first.Next)
            {
                return;
            }
            LinkedListNode<T> p = null, f = first, n = null;
            while(f != null)
            {
                n = f.Next;
                f.Next = p;
                p = f;
                f = n;
            }
            last = first;
            first = p;
        }

<递归:

        public void ReverseRecursive()
        {
            if (null == first)
            {
                return;
            }
            if (null == first.Next)
            {
                return;
            }
            last = first;
            first = this.ReverseRecursive(first);
        }
        private LinkedListNode<T> ReverseRecursive(LinkedListNode<T> node)
        {
            Debug.Assert(node != null);
            var adjNode = node.Next;
            if (adjNode == null)
            {
                return node;
            }
            var rf = this.ReverseRecursive(adjNode);
            adjNode.Next = node;
            node.Next = null;
            return rf;
        }

Here is linked reversal iterative and recursive in .net (C#)
(note the linked list is maintaining both first and last pointers so that i can append at the end or insert at head in O(1) - one doesn't have to do this. I just defined my linked list behavior as above)

public void ReverseIterative()
        {
            if(null == first)
            {
                return;
            }
            if(null == first.Next)
            {
                return;
            }
            LinkedListNode<T> p = null, f = first, n = null;
            while(f != null)
            {
                n = f.Next;
                f.Next = p;
                p = f;
                f = n;
            }
            last = first;
            first = p;
        }

Recursive:

        public void ReverseRecursive()
        {
            if (null == first)
            {
                return;
            }
            if (null == first.Next)
            {
                return;
            }
            last = first;
            first = this.ReverseRecursive(first);
        }
        private LinkedListNode<T> ReverseRecursive(LinkedListNode<T> node)
        {
            Debug.Assert(node != null);
            var adjNode = node.Next;
            if (adjNode == null)
            {
                return node;
            }
            var rf = this.ReverseRecursive(adjNode);
            adjNode.Next = node;
            node.Next = null;
            return rf;
        }
时光倒影 2024-08-25 03:42:47

您需要定义一个节点数据结构,其中包含一些数据和对链表中下一个节点的引用。类似于:

class Node {
  private Node _next;
  private string _data;

  public Node(string data) {
    _next = null;
    _data = data;
  }

  // TODO: Property accessors and functions to link up the list
}

然后您可以编写一个算法以相反的顺序循环列表,构造一个新的反向列表。

You need to define a node data structure which contains some data and a reference to the next node in the linked list. Something like:

class Node {
  private Node _next;
  private string _data;

  public Node(string data) {
    _next = null;
    _data = data;
  }

  // TODO: Property accessors and functions to link up the list
}

Then you can write an algorithm to loop over the list in reverse order, constructing a new reversed list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文