簡體   English   中英

在C#中的雙鏈表中交換節點

[英]Swapping nodes in a doubly linked list in C#

我正在嘗試使用冒泡排序對雙向鏈表進行排序。 我自己編寫了雙重鏈表類。 節點包含四個值(firstName,lastName,Id和department)。

以下是我試圖用來對列表進行排序的方法(我正在使用Windows窗體,並從窗體中調用sortList方法)。

K和I是doubleLinkedList類的節點。

public DoubleLinkedList sortList(ref DoubleLinkedList toSort)
{
  for (toSort.K = toSort.First; toSort.K != endOfTheList(toSort.First); toSort.K = toSort.K.NextLink)
  {
    for(toSort.I = toSort.K.NextLink; toSort.I != endOfTheList(toSort.First); toSort.I = toSort.I.NextLink)
    {
      if (string.Compare(toSort.K.Department, toSort.I.Department) > 0)
      {
        MessageBox.Show(toSort.ToString());
        swap( toSort, toSort.K, toSort.I);
      }
    }
  }

  MessageBox.Show("List is sorted");
  MessageBox.Show(this.ToString());
  return toSort;
}

public void swap(DoubleLinkedList swapList, Node _k, Node _i)
{
    MessageBox.Show("Swapping " + swapList.K.ToString() + "for" + swapList.I.ToString());

    Node temp = _k;
    swapList.K = _i;
    swapList.I = temp;
    MessageBox.Show(swapList.K.ToString() + swapList.I.ToString());
    MessageBox.Show(swapList.ToString());
}

第二個最后一個消息框顯示方法中已交換節點K和節點I的firstName,lastName,Id和部門,但實際上在doublelinkedlist中尚未交換它們。

如果有人可以建議我如何更改這些方法以實際交換列表中的值,將不勝感激。 我在網上找到了示例,但是它們使用的是LinkedList<>類,我真的很想使用自己的類。

例如:節點K = Michelle Sellers,12號,銷售節點I = Nick Hodges,22號,客戶

使用交換方法后,K =尼克·霍奇斯(No22),帳戶,I =米歇爾·塞勒斯(Michelle Sellers),第12,銷售,但在實際列表中未交換節點。

彼此相鄰交換節點

由於您使用BubbleSort,因此我將假設您要交換的兩個節點彼此相鄰 這是一個假設:如果不成立; 問題比較復雜。

假設您有一個雙向鏈接列表,如下所示:

First                      Last
|                          |
v                          v
+---+ -> +---+ -> +---+ -> +---+
| 1 |    | 4 |    | 2 |    | 5 |
+---+ <- +---+ <- +---+ <- +---+

-><-鏈接到NextLinkPrevLink 現在我們想例如將節點交換為42 ,則列表將如下所示:

First                      Last
|                          |
v                          v
+---+ -> +---+ -> +---+ -> +---+
| 1 |    | 2 |    | 4 |    | 5 |
+---+ <- +---+ <- +---+ <- +---+

因此,現在我們應該問自己:“發生了什么變化”:我們看到了很多變化:

  • 節點1的NextNode現在是節點2;
  • 節點2的NextNode現在是節點4;
  • 現在節點4的NextNode是節點5;
  • 節點5的PrevNode現在是節點4;
  • 節點4的PrevNode現在是節點2;
  • 節點2的PrevNode現在是節點1。

此外,如果要交換的節點之一是第first節點或last節點,那么我們也必須更新這些指針。 在那種情況下,通常沒有節點4的前一個節點(如果節點4是start節點),或者沒有節點2下一個節點(如果節點2是最后一個節點)。 因此,有很多情況。 當然,這取決於鏈接列表是否具有對第first和/或last節點的引用。

因此,我們可以編寫如下算法:

public void swap(DoubleLinkedList swapList, Node i, Node j) {
    Node h = i.PrevNode;
    Node k = j.NextNode;
    if(swapList.First == i) {
        swapList.First = j;
    }
    if(h != null) {
        h.NextNode = j;
    }
    j.PrevNode = h;
    j.NextNode = i;
    i.PrevNode = j;
    i.NextNode = k;
    if(k != null) {
        k.PrevNode = i;
    }
    if(swapList.Last == j) {
        swapList.Last = i;
    }
}

交換兩個隨機節點

如果節點是隨機的,則問題更加嚴重。 在這里,我們考慮將節點b與節點f交換的場景:

     -> +---+ -> +---+ -> +---+ ->       -> +---+ -> +---+ -> +---+ ->
...     | a |    | b |    | c |     ...     | e |    | f |    | g |     ...
     <- +---+ <- +---+ <- +---+ <-       <- +---+ <- +---+ <- +---+ <- 

如果我們想用f交換b ,我們將必須:

  • aNextNodef ;
  • fNextNodec ;
  • eNextNodeb ;
  • bNextNodeg ;
  • cPrevNodef ;
  • fPrevNodea ;
  • gPrevNodeb ;
  • bPrevNodee

因此我們可以像這樣實現:

public void swap(DoubleLinkedList swapList, Node b, Node f) {
    Node a = b.PrevNode;
    Node c = b.NextNode;
    Node e = f.PrevNode;
    Node g = f.NextNode;


    if(swapList.First == b) {
        swapList.First = f;
    } else if(swapList.First == f) {
        swapList.First = b;
    }

    if(a != null) {
        a.NextNode = f;
    }
    f.PrevNode = a;
    f.NextNode = c;
    if(c != null) {
        c.PrevNode = f;
    }

    if(e != null) {
        e.NextNode = b;
    }
    b.PrevNode = e;
    b.NextNode = g;
    if(g != null) {
        g.PrevNode = b;
    }

    if(swapList.Last == b) {
        swapList.Last = f;
    } else if(swapList.Last == f) {
        swapList.Last = b;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM