C语言中链表的插入排序

C语言中链表的插入排序,c,sorting,linked-list,infinite-loop,insertion-sort,C,Sorting,Linked List,Infinite Loop,Insertion Sort,我试图使用下面的函数对C中的链表执行插入排序,它陷入了一个无限循环。我调试了代码,发现它在第一个过程中有效,在第二个过程中陷入无限循环 void insertion_sort()//Insertion Sort function { struct Node *p = root->next; struct Node *a = NULL, *b = NULL; while(p != NULL) { a = root; whi

我试图使用下面的函数对C中的链表执行插入排序,它陷入了一个无限循环。我调试了代码,发现它在第一个过程中有效,在第二个过程中陷入无限循环

void insertion_sort()//Insertion Sort function
{
    struct Node *p = root->next;

    struct Node *a = NULL, *b = NULL;

    while(p != NULL)
    {
        a = root;

        while(a != p)
        {
            b = a;
            a = a->next;
        }

        if(b != NULL)
            b->next = a->next;
        a->next = NULL;

        struct Node *q = root;
        struct Node* r = NULL;

        while(p->data > q->data)
        {
            r = q;
            q = q->next;
        }
        p->next = q;
        if(r != NULL)
            r->next = p;

        p = p->next;
    }

}

首先,当函数依赖于全局变量时,这不是一个好主意。例如,在您的程序中,这意味着您不能在一个程序中有两个列表

我看不到在函数
insertion\u sort
中指针
root
在哪里更改。因此,即使所有其他代码都有效,该函数仍然是不正确的,因为当指向的节点的值无序时,它不会更改指针
root

我可以建议如下演示程序中所示的解决方案

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

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

int push_front( struct Node **head, int data )
{
    struct Node *node = malloc( sizeof( struct Node ) );
    int success = node != NULL;
    
    if ( success )
    {
        node->data = data;
        node->next = *head;
        
        *head = node;
    }
    
    return success;
}

void insertion_sort( struct Node **head )
{
    for ( struct Node **current = head; *current != NULL; )
    {
        struct Node **sorted = head;
        
        while ( *sorted != *current && !( ( *current )->data < ( *sorted )->data ) )
        {
            sorted = &( *sorted )->next;
        }
        
        if ( *sorted != *current )
        {
            struct Node *tmp = *current;
            *current = ( *current )->next;
            tmp->next = *sorted;
            *sorted = tmp;
        }
        else
        {
            current = &( *current )->next;
        }
    }
}

FILE * output( struct Node *head, FILE *fp )
{
    for ( ; head != NULL; head = head->next )
    {
        fprintf( fp, "%d -> ", head->data );
    }
    
    fputs( "null", fp );
    
    return fp;
}

int main(void) 
{
    enum { N = 13 };
    
    struct Node *head = NULL;
    
    srand( ( unsigned int )time( NULL ) );
    
    for ( int i = 0; i < N; i++ )
    {
        push_front( &head, rand() % N );    
    }
    
    fputc( '\n', output( head, stdout ) );
    
    insertion_sort( &head );
    
    fputc( '\n', output( head, stdout ) );
    
    return 0;
}

我马上看到一个问题:
while(a!=p)
循环更改
a
,但不检查它是否变为NULL。我有点惊讶你没有出现seg故障。与
while(p->data>q->data)
相同:它更改
q
,但从不检查
q
是否为空。解决这些问题。如果您仍然有一个无限循环,在调试过程中,检查
while
循环条件,确保它们朝着最终会产生错误测试的方向前进。为什么函数返回void?为什么不需要争论呢?为什么root是一个全局变量?
1 -> 12 -> 0 -> 4 -> 0 -> 12 -> 3 -> 7 -> 12 -> 2 -> 5 -> 9 -> 7 -> null
0 -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 7 -> 7 -> 9 -> 12 -> 12 -> 12 -> null