繁体   English   中英

交换双链表中的节点

[英]swapping nodes in doubly linked list

尝试使用以下方法从c#中的双向链接列表交换第二个和第三个节点:

public static void swapNodes(List dblLinkList)
{
    Node tempnodeTwo = dblLinkList.firstNode.next;          //node two in list
    Node tempnodeThree = dblLinkList.firstNode.next.next;   //node three in list

    Node tempnodeFive = tempnodeTwo.previous;
    Node tempnodeSix = tempnodeThree.next;

    tempnodeThree.previous = tempnodeFive;
    tempnodeThree.next = tempnodeThree;
    tempnodeTwo.previous = tempnodeTwo;
    tempnodeTwo.next = tempnodeSix;
}

下面显示了输出:第一个是原始列表,第二个是方法的结果。

N:19:16 19:16:9 16:9:15 9:15:15 15:15:N
N:19:16 16:16:15 9:15:15 15:15:N

我要去哪里错了? 我已经研究过有关此主题的先前问题,这使我有了代码的想法,但现在陷入困境!

在这些行中

  tempnodeThree.next = tempnodeThree;
  tempnodeTwo.previous = tempnodeTwo;

您将节点的下一个设置为自身,将节点的下一个设置为其自身。

你不是说

  tempnodeThree.next = tempnodeTwo;
  tempnodeTwo.previous = tempnodeThree;

我想如果您使用更好的名字,您会更轻松。

我也不会像这样实现此功能-我会让函数适合它的名称,如下所示:

public static void swapNodes(Node a, Node b)
{
  if (a == null) return;
  if (b == null) return;

  Node afterA = a.next;
  Node beforeA = a.previous;

  a.previous = b.previous;
  if (b.previous != null) b.previous.next = a;
  a.next = b.next;
  if (b.next != null) b.next.previous = a;

  b.next = afterA;
  if (afterA != null) afterA.previous = b;
  b.previous = beforeA;
  if (beforeA != null) beforeA.next = b;
}

// call it like this
swapNodes(dblLinkList.firstNode.next, dblLinkList.firstNode.next.next);

似乎您假设tempnodeThreetempnodeThree的第三个节点,而tempnodeTwo是链表的第二个节点,而不管您进行的更改如何,但这不是事实。

初始化之后,您将得到:

tempnodeFive <-> tempnodeTwo <-> tempnodeThree <-> tempnodeSix

您需要的是:

tempnodeFive <-> tempnodeThree <-> tempnodeTwo <-> tempnodeSix

因此,您需要从左到右更改的内容是:

tempNodeFive.nexttempNodeTwo.previoustempNodeTwo.nexttempNodeThree.previoustempNodeThree.nexttempNodeSix.previous

让我们按照第二个链表表示法进行研究:

tempNodeFive.next = tempNodeThree;
tempNodeTwo.previous = tempnodeThree;
tempNodeTwo.next = tempnodeSix;
tempNodeThree.previous = tempnodeFive;
tempNodeThree.next = tempnodeTwo;
tempNodeSix.previous = tempnodeTwo;

这六行是您需要的。

PS:您可以重新考虑变量名称,以获取可读和可维护的代码,尤其是。 tempNodeFive和tempnodeSix,因为5和6作为索引没有任何意义,并且在读取代码时会引起混乱。

您确定是c#吗? 看起来像java。 C#具有LinkedListNode<T>类,而不是Node 并且LinkedListNode<T>具有NextPrevious属性。 首都 并且它们是只读的

c#实现的任何方式如下所示:

using System;
using System.Collections.Generic;

namespace LinkedListSwap
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new LinkedList<string>(new[] { "1st", "2nd", "3rd", "4th", "5th", "6th", "7th" });
            Console.WriteLine(list.ToDisplayString());
            list.Swap(2, 3);
            Console.WriteLine(list.ToDisplayString());
        }
    }

    static class LinkedListExtensions
    {
        public static void Swap<T>(this LinkedList<T> list, int firstIndex, int secondIndex)
        {
            if (firstIndex < 1 || firstIndex > list.Count)
                throw new IndexOutOfRangeException($"Index out of range: {nameof(firstIndex)}");

            if (secondIndex < 1 || secondIndex > list.Count)
                throw new IndexOutOfRangeException($"Index out of range: {nameof(secondIndex)}");

            if (firstIndex == secondIndex)
                return;

            if (firstIndex > secondIndex)
                (firstIndex, secondIndex) = (secondIndex, firstIndex);

            int i = 0;

            var leftNode = list.First;
            while (++i < firstIndex)
                leftNode = leftNode.Next;

            var rightNode = leftNode.Next;
            while (++i < secondIndex)
                rightNode = rightNode.Next;

            list.Replace(leftNode, rightNode);
            list.Replace(rightNode, leftNode);
        }

        public static void Replace<T>(this LinkedList<T> list, LinkedListNode<T> oldNode, LinkedListNode<T> newNode)
        {
            list.AddAfter(oldNode, new LinkedListNode<T>(newNode.Value));
            list.Remove(oldNode);
        }

        public static string ToDisplayString<T>(this LinkedList<T> list) => string.Join(" ", list);
    }
}

输出为:

1st 2nd 3rd 4th 5th 6th 7th
1st 3rd 2nd 4th 5th 6th 7th

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM