[英]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);
似乎您假設tempnodeThree
是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作為索引沒有任何意義,並且在讀取代碼時會引起混亂。
您確定是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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.