【问题标题】:How do you copy a linked list into another list?如何将一个链表复制到另一个链表中?
【发布时间】:2011-06-26 10:12:50
【问题描述】:

我正在研究数据结构和链表,但我不了解如何制作链表的副本。有人可以解释一下吗,可能使用伪代码或 C 代码?

【问题讨论】:

    标签: c algorithm data-structures linked-list


    【解决方案1】:

    复制链表的逻辑是递归的,基于以下观察:

    1. 空列表的克隆是空列表。
    2. 具有第一个节点 x 和其余节点 xs 的列表的克隆是附加到 xs 的克隆的 x 的副本。

    如果你用 C++ 对链表进行编码,这会非常干净:

    struct Node {
        int value;
        Node* next;
    };
    
    Node* Clone(Node* list) {
        if (list == NULL) return NULL;
    
        Node* result = new Node;
        result->value = list->value;
        result->next = Clone(list->next);
        return result;
    }
    

    【讨论】:

      【解决方案2】:

      您了解如何将新节点添加到现有列表中吗?您是否了解如何遍历(即迭代)列表?复制列表只是同时执行这两个操作(遍历 ListA;对于每个元素,复制该元素并将其作为新节点添加到 ListB)。

      【讨论】:

        【解决方案3】:

        这个帖子的答案已经给出并被接受——一切都很好! 但是,如果有人正在寻找 C# 中的迭代方法,这里是:

        Node 类:

        public class Node
        {
            public Node(int val)
            {
                Val = val;
            }
        
            public Node Next { get; set; }
            public int Val { get; }
        }
        

        这里是迭代实现:

        public Node CopyLinkedListIteratively(Node head)
        {
            // validation:
            if (head == null) return null;
        
            // current node is always a 'new' node with value.
            Node currentNode = new Node(head.Val);
        
            // set copyList and previous to current node to start with - which is true at this point in time!
            Node copyList = currentNode;
            Node previous = currentNode;
            
            // move head one step forward as we already have copied its value.
            head = head.Next;
        
            // keep moving until we hit a null reference which is the end.
            while (head != null)
            {
                currentNode = new Node(head.Val); // create a new node every time as we move forward.
                previous.Next = currentNode; // set previous node's next to current node as previous node itself is one step behind the current.
                previous = previous.Next; // move prev pointer forward
                head = head.Next; // move head pointer forward as well
            }
        
            // return the reference to copyList.
            // copyList and previous both started off pointing to the currentNode, then in the while loop
            // previous kept moving forward till all nodes are copied.
            // copyList reference never moved from its position so its still pointing at the start.
            return copyList;
        }
        

        时间复杂度:O(n)

        空间复杂度:O(n)

        其中 n = 链表中的节点数。

        个人偏好使用递归或迭代方法,但是我建议在使用递归时考虑函数调用堆栈。

        单元测试:

        [Test]
        public void CopyLinkedListIterativelyTest()
        {
            Node head = new Node(1);
            head.Next = new Node(2);
            head.Next.Next = new Node(3);
            head.Next.Next.Next = new Node(4);
            head.Next.Next.Next.Next = new Node(5);
        
            var actual = runner.CopyLinkedListIteratively(head);
        
            while (actual != null)
            {
                Assert.AreEqual(head.Val, actual.Val);
                actual = actual.Next;
                head = head.Next;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多