簡體   English   中英

作業,鏈表氣泡排序

[英]Homework, 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;
}

您需要在每個外部循環中重置工作指針:

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

代碼還交換了節點的內容,而不是更改節點鏈接來完成排序。 我不確定這是否允許您進行課程分配。

如果您需要更改鏈接而不是使用冒泡排序(通過鏈接交換節點很復雜),則創建新的空列表將更加簡單,例如:

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

然后一次從原始列表中刪除一個節點,然后按順序將其插入要排序的列表中。 自下而上的合並排序之類的其他方法會更快,但遠遠超出了您對此類類分配的期望。

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

創建指向節點的指針數組,對指針數組進行排序,然后根據已排序的指針數組重新鏈接列表,這仍然會更快,但這需要O(n)空間,而且不是鏈接列表排序。

您的交換功能正在復制節點的完整內容。 這將是非常低效的,非常特定於節點的內容,當內容更改時,任何持有指向這些節點的指針的人都會感到非常驚訝。 一個好的排序算法只需要知道排序標准。

相反,應該只保留節點的內容,然后在列表中重新鏈接它們。 您可能已經注意到,使用一個鏈接列表來“冒泡”,您需要兩個節點和前一個節點。 相反,不要將較小的物品冒泡,而將較大的物品往下推。

這是基本算法。

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

有關更多信息,請參見此鏈接列表氣泡排序示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM