繁体   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