简体   繁体   English

链表的合并排序代码仅对 C 中的一半元素进行排序

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

I have some code to merge sort a linked list that contains strings as the data value.我有一些代码可以对包含字符串作为数据值的链表进行合并排序。 My goal is to sort the nodes in the linked list in alphabetical order.我的目标是按字母顺序对链表中的节点进行排序。

Here is how I am defining my nodes:这是我定义节点的方式:

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

And this is the call that I am making to sort the list in my main:这是我在主目录中对列表进行排序的调用:

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

The push function inserts an element to the start of a linked list, while the printList function will print each element in the list followed by a newline. push function 将一个元素插入到链表的开头,而printList function 将打印列表中的每个元素,后跟一个换行符。

I can confirm that the push and printList functions are working properly as all the elements of the list a are printed as expected when I test that.我可以确认pushprintList函数工作正常,因为列表a的所有元素在我测试时都按预期打印。

Here is the code I am using to sort the list in alphabetical order:这是我用来按字母顺序对列表进行排序的代码:

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

When I print the list sorted after the sorting process, my output looks like this:当我打印sorted过程后排序的列表时,我的 output 看起来像这样:

Sorted Linked List is: 
grapes
kiwi
strawberry

Which shows that the sorting is working properly, however not all of the elements are being outputted.这表明排序工作正常,但并非所有元素都被输出。 I was wondering why this might be the case?我想知道为什么会这样?

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

Here is the faulty part.这是错误的部分。 You are sorting the sub-lists, but after having sorted them, you are not updating a and b to point to the corresponding new heads of the lists.您正在对子列表进行排序,但是在对它们进行排序之后,您并没有更新ab以指向列表的相应新头。

Change to改成

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

and it behaves as expected.它的行为符合预期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM