家庭作业,链表冒泡排序

时间:2017-04-26 21:50:06

标签: c linked-list bubble-sort

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

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;
}

2 个答案:

答案 0 :(得分:2)

您需要重置每个外循环中的工作指针:

    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)空间,并且它会更快不是链表排序。

答案 1 :(得分:0)

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

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

这是基本算法。

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