【问题标题】:Sorting a singly Linked List对单链表进行排序
【发布时间】:2016-11-11 16:38:02
【问题描述】:
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}

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

注意:我已经检查了下面链接中的问题,它与我的问题不同。 Sorting a Singly Linked List With Pointers

【问题讨论】:

  • 查找您为head 分配新值的位置。
  • 使用调试器和一小组数字找出head指针发生变化的地方。
  • 我无法在循环内更改头部,因为如果我这样做,头部将继续变化直到最后一次迭代,我只想在获得 smalles 值时更改一次。这就是我使用两个指针交换它们但仍然保存它们的值以便稍后我可以连接新交换的指针的原因。

标签: c++ sorting data-structures linked-list


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    list 的排序并不像您的代码中显示的那么容易:

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

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

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

    如何做到这一点:

    1. 存储next1next2,并随时跟踪prev1prev2,因为您在单链表中无法回头
    2. first-&gt;next = next2second-&gt;next = next1
    3. prev1-&gt;next = secondprev2-&gt;next = first

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

    【讨论】:

    • 你能给出一个将按错误顺序排序的输入吗(假设已经完成了摇头的简单修复)?如果你有反例,我会 +1,因为我懒得检查。
    • 是的,当first-&gt;next=second。这些事情确实需要注意。我只是概述了所有可能的链接。
    • 这不是反例。一个反例是 {5, 3, 1, 4, 2},它给出了 {5, 1, 3} 的排序输出。该死的让我写一个测试。
    • @SauravSahu - 步骤 2 和 3 需要颠倒来处理要交换的节点相邻的情况和它们不相邻的情况。 prev -> next 指针需要在 first 和 second -> next 指针之前交换。
    【解决方案3】:

    正如 Kenny Ostrom 所指出的,即使 head 问题得到解决,如果学生 id 的初始序列是 5,3,1,4,2,那么排序结果是 5,1,3,未排序并丢失两个值。

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

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

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

    从一个空的“排序”列表开始会更简单,然后从原始列表中一次删除一个节点,并将该节点插入到“排序”列表中的适当位置。对于这种方法,从 Node * sorted = NULL 开始;一旦所有节点都从原始列表中删除并按顺序插入“排序”中,然后设置 head = sorted,以便 head 指向排序列表。

    一种更快的对链表进行排序的方法是使用一个小型(25 到 32)个指向节点的指针数组并结合自下而上的归并排序,但这比本例所需的要多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 2022-10-04
      • 2011-12-26
      • 2013-11-02
      相关资源
      最近更新 更多