【问题标题】:Homework, linked list bubble sort作业,链表冒泡排序
【发布时间】:2017-04-26 21:50:06
【问题描述】:

我的作业有点问题,我必须使用链表,问题是排序功能,我选择了冒泡排序算法,这是一段代码。

void BubbleSort(PrikazStruct **Seznam) {
    int Prohozeno = NULL;
    int Value_1, Value_2;

    PrikazStruct *AktualniPrikaz = *Seznam;
    PrikazStruct *Temp = AktualniPrikaz->Dalsi;

    Value_1 = AktualniPrikaz->Jmeno[0];
    Value_2 = AktualniPrikaz->Dalsi->Jmeno[0];

    do {
        Prohozeno = 1;

        while (AktualniPrikaz->Dalsi != NULL) {
            if (Value_1 < Value_2) {
                ProhodCleny(AktualniPrikaz, AktualniPrikaz->Dalsi);
                Prohozeno = 0;
            }

            Value_1 = AktualniPrikaz->Jmeno[0];
            AktualniPrikaz = AktualniPrikaz->Dalsi;
            Value_2 = AktualniPrikaz->Jmeno[0];

        }

    } while (!Prohozeno);

    return;
}

我不明白为什么,它没有正确排序列表,这是结构交换功能

void ProhodCleny(PrikazStruct *S1, PrikazStruct *S2) {
    PrikazStruct *Temp = (PrikazStruct *) malloc(sizeof(PrikazStruct));

    Temp->ID = S1->ID;
    strcpy(Temp->Jmeno, S1->Jmeno);
    strcpy(Temp->Prijmeni, S1->Prijmeni);
    Temp->Castka = S1->Castka;
    strcpy(Temp->Popis, S1->Popis);
    Temp->Obdobi = S1->Obdobi;
    strcpy(Temp->stringObdobi, S1->stringObdobi);
    strcpy(Temp->JePlatba, S1->JePlatba);

    S1->ID = S2->ID;
    strcpy(S1->Jmeno, S2->Jmeno);
    strcpy(S1->Prijmeni, S2->Prijmeni);
    S1->Castka = S2->Castka;
    strcpy(S1->Popis, S2->Popis);
    S1->Obdobi = S2->Obdobi;
    strcpy(S1->stringObdobi, S2->stringObdobi);
    strcpy(S1->JePlatba, S2->JePlatba);

    S2->ID = Temp->ID;
    strcpy(S2->Jmeno, Temp->Jmeno);
    strcpy(S2->Prijmeni, Temp->Prijmeni);
    S2->Castka = Temp->Castka;
    strcpy(S2->Popis, Temp->Popis);
    S2->Obdobi = Temp->Obdobi;
    strcpy(S2->stringObdobi, Temp->stringObdobi);
    strcpy(S2->JePlatba, Temp->JePlatba);

    free(Temp);
    return;
}

【问题讨论】:

  • 简短的示例输入、期望的输出和实际输出会有所帮助
  • 哦,当然,输出应该是 C、B、A,但由于某种原因,我得到了输出 C、A、B,并且我确定 if 语句被执行了第二次。输入是A、B、C

标签: c linked-list bubble-sort


【解决方案1】:

你需要在每个外循环中重置工作指针:

    Prohozeno = 1;               /* after this line */
    AktualniPrikaz = *Seznam;    /*   add this line */

代码也是交换节点的内容,而不是改变节点链接来完成排序。我不确定你的课堂作业是否允许这样做。

如果您需要更改链接而不是使用冒泡排序(通过链接交换节点很复杂),创建一个新的空列表会更简单,例如:

PrikazStruct *Sorted = NULL;    /* this will be sorted list */

然后从原始列表中一次删除一个节点,并将它们按顺序插入到要排序的列表中。其他方法(例如自下而上合并排序)会更快,但远远超出您对此类分配的预期。

https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists

创建一个指向节点的指针数组,对指针数组进行排序,然后根据排序后的指针数组重新链接列表会更快,但这需要 O(n) 空间,而且它不是链表排序。

【讨论】:

    【解决方案2】:

    您的交换功能正在复制节点的完整内容。这将是非常低效的,非常特定于节点的内容,并且任何持有指向这些节点的指针的人都会在内容发生变化时感到非常惊讶。一个好的排序算法只需要知道排序标准。

    相反,它应该单独保留节点的内容并将它们重新链接到列表中。您可能已经注意到,使用单个链表“冒泡”您需要两个节点和前一个节点。相反,不要让较小的项目冒泡,而是将较大的项目向下推。

    这是基本算法。

    while( changed ) {
        changed = 0;
    
        /* I believe you forgot this part */
        q = top;
        p = top->next;
    
        while( p->next != NULL ) {
            /* push bigger items down */
            if( p->data > p->next->data ) {
                q->next = list_switch( p, p->next );
                changed = 1;
            }
    
            q = p;
    
            if( p->next != NULL ) {
                p = p->next;
            }
        }
    }
    

    而且交换功能很简单。

    LIST *list_switch( LIST *l1, LIST *l2 )
    {
        l1->next = l2->next;
        l2->next = l1;
        return l2;
    }
    

    有关更多信息,请参阅此Linked List Bubble Sort example

    【讨论】:

    • 我也谢谢你,但是我有问题,当我第二次调用bubblesort函数时,输出被破坏了,例如,第一次是ABC,第二次是唯一的A
    • @スラフロスチ 对不起,有很多事情可能会导致这种情况。没有Minimal, Complete, Verifiable example 我不能说什么。我建议使用像 Valgrind 这样的内存检查器。
    猜你喜欢
    • 2010-10-28
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    相关资源
    最近更新 更多