对单链表进行排序

Sorting a singly Linked List

本文关键字:排序 链表 单链表      更新时间:2023-10-16
void NodeList::sortNodeAscending()
{
Node* swap = NULL;
Node* saveLink = NULL;

for(Node* firstPointer = head; firstPointer;firstPointer = firstPointer->next)
    for(Node* secondPointer = firstPointer->next; secondPointer;secondPointer = secondPointer->next)
    {
        if((secondPointer->studentId)<(firstPointer->studentId))
        {
            swap =firstPointer; 
            saveLink = secondPointer->next; 
            firstPointer = secondPointer; 
            secondPointer = swap; 
            firstPointer->next = secondPointer; 
            secondPointer->next = saveLink;

        }
    }
}

这是我的代码排序,但我有排序后的问题,所有的值都是正确的,但头部没有改变或排序。


输出:{ 5, 0, 1, 2, 3, 4, 12, 15}

除第一个节点外的所有元素都已排序。

注意:我已经检查了下面链接中的问题,它与我的问题不同。使用指针对单链表进行排序

您没有更新head以指向列表的新起点。在外部循环的第一次迭代结束时,firstPointer将指向最小的元素,并且可以更新为新的元素头。

列表进行排序并不像代码中显示的那么容易:

[prev1]   [first]   [next1] ... [prev2]   [second]   [next2]

在第一个与第二个交换时应该是这样的:

[prev1]   [second]   [next1] ... [prev2]   [first]   [next2]

怎么做:

  1. 存储next1next2,并随时跟踪prev1prev2,因为无法在单链表中查看
  2. first->next = next2second->next = next1
  3. prev1->next = secondprev2->next = first

在此过程中,您需要特别注意list的head

正如Kenny Ostrom所指出的,即使头部问题是固定的,如果学生id的初始序列是5,3,1,4,2,那么排序最终为5,1,3,未排序并丢失两个值。

代码正在交换firstPointer和secondPointer,它们被用作内部和外部循环变量。这会产生一个问题。

当交换链表中的节点时,节点可能是相邻的(三个下一个指针旋转),也可能是不相邻的(两对下一个指针交换)。要用相同的代码处理这两种情况,首先交换指向要交换的两个节点的指针(如将prev1->next与prev2->next交换),然后交换两个节点的next指针(如将curr1->next与curr2->next交换)。

尝试使用冒泡排序或任何交换排序对链表进行排序是复杂的,因为您需要跟踪两个先前指向节点的指针以及两个当前指向节点的指针。

从一个空的"已排序"列表开始,然后从原始列表中每次删除一个节点,并将节点插入到"已排序"列表中的适当位置,这样会更简单。对于这个方法,从Node * sorted = NULL开始;一旦从原始列表中删除所有节点并按顺序插入到"sorted"中,则set head = sorted,使head指向已排序的列表。

对链表进行排序的一种更快的方法是使用一个小的(25到32)指向节点的指针数组,并结合自下而上的归并排序,但在这种情况下,这已经超出了需要的范围。