尝试使用以下方法从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
我要去哪里错了?我已经研究过有关该主题的先前问题,这些问题使我对代码有所了解,但现在遇到了麻烦!
答案 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.next
,tempNodeTwo.previous
,tempNodeTwo.next
,tempNodeThree.previous
,tempNodeThree.next
,tempNodeSix.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>
具有Next
和Previous
属性。具有资本。并且它们只读。
任何以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