簡體   English   中英

鏈表的合並排序代碼僅對 C 中的一半元素進行排序

[英]Merge sort code for linked list only sorting half the elements in C

我有一些代碼可以對包含字符串作為數據值的鏈表進行合並排序。 我的目標是按字母順序對鏈表中的節點進行排序。

這是我定義節點的方式:

struct Node { 
    void *data; 
    struct Node* next; 
}; 

這是我在主目錄中對列表進行排序的調用:

int main() 
{ 

    struct Node* a = NULL; 
    struct Node* sorted = NULL;

    push(&a, "orange"); 
    push(&a, "banana"); 
    push(&a, "strawberry"); 
    push(&a, "apple"); 
    push(&a, "kiwi"); 
    push(&a, "grapes"); 

    sorted = MergeSort(a); 

    printf("Sorted Linked List is: \n"); 
    printList(sorted); 

    return 0; 
} 

push function 將一個元素插入到鏈表的開頭,而printList function 將打印列表中的每個元素,后跟一個換行符。

我可以確認pushprintList函數工作正常,因為列表a的所有元素在我測試時都按預期打印。

這是我用來按字母順序對列表進行排序的代碼:

/* sorts the linked list by changing next pointers (not data) */
struct Node* MergeSort(struct Node* headRef) 
{ 
    struct Node* head = headRef; 
    struct Node* a; 
    struct Node* b; 

    /* Base case -- length 0 or 1 */
    if ((head == NULL) || (head->next == NULL)) { 
        return headRef; 
    } 

    /* Split head into 'a' and 'b' sublists */
    FrontBackSplit(head, &a, &b); 

    /* Recursively sort the sublists */
    MergeSort(a); 
    MergeSort(b); 

    /* answer = merge the two sorted lists together */
    headRef = SortedMerge(a, b); 
    return headRef;
} 


struct Node* SortedMerge(struct Node* a, struct Node* b) 
{ 
    struct Node* result = NULL; 

    /* Base cases */
    if (a == NULL) 
        return (b); 
    else if (b == NULL) 
        return (a); 

    /* Pick either a or b, and recur */
    if (strcmp(a->data, b->data) <= 0) { 
        result = a; 
        result->next = SortedMerge(a->next, b); 
    } 
    else { 
        result = b; 
        result->next = SortedMerge(a, b->next); 
    } 
    return (result); 
} 

/* UTILITY FUNCTIONS */
/* Split the nodes of the given list into front and back halves, 
    and return the two lists using the reference parameters. 
    If the length is odd, the extra node should go in the front list. 
    Uses the fast/slow pointer strategy. */
void FrontBackSplit(struct Node* source, 
                    struct Node** frontRef, struct Node** backRef) 
{ 
    struct Node* fast; 
    struct Node* slow; 
    slow = source; 
    fast = source->next; 

    /* Advance 'fast' two nodes, and advance 'slow' one node */
    while (fast != NULL) { 
        fast = fast->next; 
        if (fast != NULL) { 
            slow = slow->next; 
            fast = fast->next; 
        } 
    } 

    /* 'slow' is before the midpoint in the list, so split it in two 
    at that point. */
    *frontRef = source; 
    *backRef = slow->next; 
    slow->next = NULL; 
} 

當我打印sorted過程后排序的列表時,我的 output 看起來像這樣:

Sorted Linked List is: 
grapes
kiwi
strawberry

這表明排序工作正常,但並非所有元素都被輸出。 我想知道為什么會這樣?

/* Recursively sort the sublists */
MergeSort(a); 
MergeSort(b); 

這是錯誤的部分。 您正在對子列表進行排序,但是在對它們進行排序之后,您並沒有更新ab以指向列表的相應新頭。

改成

/* Recursively sort the sublists */
a = MergeSort(a); 
b = MergeSort(b); 

它的行為符合預期。

暫無
暫無

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

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