我正在尝试使用冒泡排序对双向链表进行排序。我自己编写了双链表。节点包含四个值(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和部门已在方法中交换,但它们实际上没有交换双链接列表。
如果有人可以就如何更改这些方法以实际交换列表中的值给我建议,那将非常感激。我在网上找到了例子,但他们使用的是LinkedList<>
类,我真的很想使用自己的类。
作为一个例子:Node K = Michelle Sellers,No12,Sales 节点I = Nick Hodges,No22,Accounts
在交换方法之后,K = Nick Hodges,No22,Accounts和I = Michelle Sellers,No12,Sales,但在实际列表中,节点不会被交换。
答案 0 :(得分:0)
由于您使用BubbleSort,我将假设您要交换的两个节点彼此相邻。这是一个假设:如果这不成立;问题更复杂。
假设您有一个双重链接列表,如下所示:
First Last
| |
v v
+---+ -> +---+ -> +---+ -> +---+
| 1 | | 4 | | 2 | | 5 |
+---+ <- +---+ <- +---+ <- +---+
->
和<-
指向NextLink
和PrevLink
的链接。现在我们希望用4
和2
交换节点,然后列表如下:
First Last
| |
v v
+---+ -> +---+ -> +---+ -> +---+
| 1 | | 2 | | 4 | | 5 |
+---+ <- +---+ <- +---+ <- +---+
所以现在我们应该问自己:“发生了什么变化”:我们看到了很多变化:
NextNode
现在是节点2; NextNode
现在是节点4; NextNode
现在是节点5; PrevNode
现在是节点4; PrevNode
现在是节点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 | ...
<- +---+ <- +---+ <- +---+ <- <- +---+ <- +---+ <- +---+ <-
如果我们想将b
与f
交换,我们将不得不:
a
的{{1}}成为NextNode
; f
的{{1}}成为f
; NextNode
的{{1}}成为c
; e
的{{1}}成为NextNode
; b
的{{1}}成为b
; NextNode
的{{1}}成为g
; c
PrevNode
成为f
;和f
的{{1}}成为PrevNode
。所以我们可以这样实现:
a