C 对链表进行排序(错误)

C 对链表进行排序(错误),c,sorting,pointers,linked-list,C,Sorting,Pointers,Linked List,我目前正在把C语言中的链表排序作为家庭作业。我不是在寻找一个代码片段作为答案,因为我知道自己弄明白它的价值。我使用下面的功能收到segfault,如果有人能告诉我原因,我将非常感激。我所能理解的最好情况是,当达到以下标准时,它正在失败: 如果(头->值->头->下一步->值){ 编辑:将此行更改为if(head->next!=NULL&&head->value->head->next->value){并且我不再接收segfaults。但是,我的输出head指针正在给我链接列表中的最后一个节点。H

我目前正在把C语言中的链表排序作为家庭作业。我不是在寻找一个代码片段作为答案,因为我知道自己弄明白它的价值。我使用下面的功能收到segfault,如果有人能告诉我原因,我将非常感激。我所能理解的最好情况是,当达到以下标准时,它正在失败:

如果(头->值->头->下一步->值){

编辑:将此行更改为if(head->next!=NULL&&head->value->head->next->value){并且我不再接收segfaults。但是,我的输出head指针正在给我链接列表中的最后一个节点。HALP

我不完全确定从这里走到哪里,即使是在正确的方向上的最轻微的推动也会非常感激

struct node *sort_list(struct node *head) {
    bool swapped ;
    struct node * tmp , * orig ;
    orig = head ;

    if ( head == NULL || head->next == NULL ) return head ;
    else {
            do {
                    swapped = false ;
                    if ( head->next != NULL && head->value > head->next->value ) {
                            tmp = head ;
                            head = head->next ;
                            tmp->next = head->next ;
                            head->next = tmp ;

                            swapped = true ;
                    }
                    head = head->next ;
            } while ( swapped == true && head != NULL ) ;
    }
    return orig ;
}

当你进入
do
循环时,你知道
head->next
不是
NULL
,但是下一轮呢,或者当你到达最后一个项目时呢?最后一个项目后面没有任何东西

编辑:


假设您按顺序有3个项目,
A
B
C
,其中
head==B
,并且您希望交换项目
B
C
。当您进入
do
循环时,您没有考虑到您还需要执行
A->next=C
,您知道
head next
不是
NULL
,但是下一轮呢,或者当你到达最后一项时呢?最后一项之后没有任何内容

编辑:


假设您按顺序有3个项目,
A
B
C
,其中
head==B
,并且您希望交换项目
B
C
。您没有考虑到您还需要执行
A->next=C
,这很可能是由空指针取消引用引起的


您没有检查循环中的
head->next
是否为空。在第一次迭代后,
head
变为
head->next
,并且您的条件(
if(head->value>head->next->value)
)正在取消引用
以访问
下一步->值

,这很可能是由空指针取消引用引起的


您没有检查循环中的
head->next
是否为空。在第一次迭代后,
head
变为
head->next
,并且您的条件(
if(head->value>head->next->value)
)取消引用
head
以访问
value
next->value
head->next
可能为空。您正在检查它是否在循环之前,但
while
条件不执行该检查


你应该找到一个
gdb
教程,它是一个非常强大的工具,可以处理类似的事情。

head->next
可能为空。你正在检查它是否在循环之前,但是
while
条件不执行该检查


你应该找到一个
gdb
教程,它是一个非常强大的工具,可以处理类似的事情。

一旦head成为链表中的最后一个元素,你就得到了segfault。
我不想写代码,因为这是家庭作业,但添加一个条件来检查head->next是否为null。如果为null,则需要将head设置回列表的开头

冒泡排序需要多次通过链表进行排序。如果使用值5,4,3,2,1和打印头以及打印温度和打印头初始化链表,则可能会看到5,4 5,3 5,2 5,1 SEGFULT

此外,您的排序公式似乎有点不正确。如果您有数据,如2,3,1。您的代码将看到2和3,swapped将变为true,函数将返回true

您可能希望使用内部循环进行循环,以便外部循环的每次迭代都会导致1次通过链接列表。如果在通过整个链接列表后没有交换,则会对数据进行排序

do{
    for 1 pass through linked list (this can be a for or while loop)
        swap if necessary; set swapped to true
}while(swapped is true)
希望这有帮助

编辑

之后

您需要维护头部指针。
在5,4,3,6的情况下,它将按如下方式进行排序
4,5,3,6
4,3,5,6
3,4,5,6

但是您的原始指针从未更新,因此您的输出将被截断为4,5,6。

一旦head成为链接列表中的最后一个元素,您将获得segfault。
我不想写代码,因为这是家庭作业,但添加一个条件来检查head->next是否为null。如果为null,则需要将head设置回列表的开头

冒泡排序需要多次通过链表进行排序。如果使用值5,4,3,2,1和打印头以及打印温度和打印头初始化链表,则可能会看到5,4 5,3 5,2 5,1 SEGFULT

此外,您的排序公式似乎有点不正确。如果您有数据,如2,3,1。您的代码将看到2和3,swapped将变为true,函数将返回true

您可能希望使用内部循环进行循环,以便外部循环的每次迭代都会导致1次通过链接列表。如果在通过整个链接列表后没有交换,则会对数据进行排序

do{
    for 1 pass through linked list (this can be a for or while loop)
        swap if necessary; set swapped to true
}while(swapped is true)
希望这有帮助

编辑

之后

您需要维护头部指针。
在5,4,3,6的情况下,它将按如下方式进行排序
4,5,3,6
4,3,5,6
3,4,5,6

但是您的原始指针从未更新过,因此您的输出将被截断为4,5,6。

我没有立即发现问题,但如果我是您,我会进行
交换(…)
函数,它接受交换代码并将其放入自己的函数中。然后您可以测试该函数,直到您确信它能工作。一旦您有了它,您就可以专注于排序逻辑。就目前而言,您必须首先弄清楚是您的排序逻辑还是交换逻辑出了问题。这将是一项值得您花时间来解决的投资学习如何使用调试器。
head = head->next  
if(tmp == orig)  
    orig = head;