Exemple #1
0
        public static ComplexLinkedListNode Execute(ComplexLinkedListNode head)
        {
            if (head == null)
            {
                throw new ArgumentNullException(nameof(head), "The input linked list can't be null");
            }

            //return CopyUsingHash(head);
            return(Copy(head));
        }
Exemple #2
0
        public void LinkedListWithOnlyOneNode()
        {
            var oldNode = new ComplexLinkedListNode(20);
            var newNode = CopyComplexLinkedList.Execute(oldNode);

            Assert.Equal(oldNode.Value, newNode.Value);
            Assert.NotEqual(oldNode, newNode);
            Assert.Null(oldNode.Next);
            Assert.Null(newNode.Next);
            Assert.Null(oldNode.Sibling);
            Assert.Null(newNode.Sibling);
        }
Exemple #3
0
        private static ComplexLinkedListNode Copy(ComplexLinkedListNode head)
        {
            // 将每个节点复制后,就接在本节点后面,再往后才是剩下的节点
            var currentNode = head;
            var nextNode    = head.Next;

            while (currentNode != null)
            {
                var newNode = new ComplexLinkedListNode(currentNode.Value);
                currentNode.Next = newNode;
                newNode.Next     = nextNode;

                currentNode = nextNode;
                nextNode    = nextNode?.Next;
            }

            // 重建sibling关系
            currentNode = head;
            while (currentNode != null)
            {
                if (currentNode.Sibling != null)
                {
                    currentNode.Next.Sibling = currentNode.Sibling.Next;
                }

                currentNode = currentNode.Next.Next;
            }

            // 拆分出新链表,并且会还原原始链表
            var old        = head;
            var oldToNew   = head.Next;
            var newHead    = oldToNew;
            var newCurrent = newHead;

            while (oldToNew.Next != null)
            {
                old.Next = oldToNew.Next;
                old      = old.Next;

                oldToNew        = oldToNew.Next.Next;
                newCurrent.Next = oldToNew;

                newCurrent = newCurrent.Next;
            }

            // 上面循环结束的时候,原链表最后一个节点指向的是新链表最后一个节点,需要手动指向null,才能完全恢复原始链表
            old.Next = null;

            return(newHead);
        }
Exemple #4
0
        // 利用hash关联新旧两个链表中的值,时间效率很高,但是需要占用额外空间
        private static ComplexLinkedListNode CopyUsingHash(ComplexLinkedListNode head)
        {
            var       newHead = new ComplexLinkedListNode(head.Value);
            Hashtable hash    = new Hashtable
            {
                { head, newHead }
            };

            // 复制链表
            var oldCurrent = head;
            var newCurrent = newHead;

            while (oldCurrent.Next != null)
            {
                oldCurrent = oldCurrent.Next;

                newCurrent.Next = new ComplexLinkedListNode(oldCurrent.Value);
                newCurrent      = newCurrent.Next;
                // 记录新旧链表对应节点的关系,这样在第二轮遍历重建Sibling关系时,只需要O(1)的查找时间
                hash.Add(oldCurrent, newCurrent);
            }

            // 重建Sibling关系
            oldCurrent = head;
            newCurrent = newHead;
            while (oldCurrent != null)
            {
                // 当旧链表节点有Sibling节点时,给新链表也加上对应的关系(通过hash查找加快速度)
                if (oldCurrent.Sibling != null)
                {
                    newCurrent.Sibling = (ComplexLinkedListNode)hash[oldCurrent.Sibling];
                }

                oldCurrent = oldCurrent.Next;
                newCurrent = newCurrent.Next;
            }

            return(newHead);
        }