簡體   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