交换双链表中的节点

时间:2019-04-29 16:49:06

标签: c#

尝试使用以下方法从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

我要去哪里错了?我已经研究过有关该主题的先前问题,这些问题使我对代码有所了解,但现在遇到了麻烦!

3 个答案:

答案 0 :(得分:1)

在这些行中

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

答案 1 :(得分:1)

您似乎假设tempnodeThree是第三个节点,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作为索引没有任何意义,并且在读取代码时会引起混乱。

答案 2 :(得分:1)

确定是 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