C 链表上的冒泡排序

C 链表上的冒泡排序,c,sorting,data-structures,struct,linked-list,C,Sorting,Data Structures,Struct,Linked List,我试图编写一个冒泡排序的实现来对链表进行排序,但目前它导致我的程序崩溃 以下是结构的定义方式: typedef struct shopping_cart cart; struct shopping_cart{ char *item_name; int quantity; cart *next; }; 这是我的代码: void sort(cart *head){ cart *i, *j; cart *second = get_second(head);

我试图编写一个冒泡排序的实现来对链表进行排序,但目前它导致我的程序崩溃

以下是结构的定义方式:

typedef struct shopping_cart cart;
struct shopping_cart{
    char *item_name;
    int quantity;
    cart *next;
};
这是我的代码:

void sort(cart *head){
    cart *i, *j;
    cart *second = get_second(head);
    cart *last = get_end_of_cart(head);

    for(i = second; i != NULL; i = i->next){
        for(j = head; j != last; j = j->next){
            if ((compare(j, j->next) > 0)){
                swap(j, j->next);
            }
        }
    }
}

void swap(cart *ptr1, cart *ptr2){
    cart *temp;
    temp = ptr1;
    ptr1 = ptr2;
    ptr2 = temp;
}

cart *get_end_of_cart(cart *head){
    cart *_next = head;

    while (_next->next != NULL){
        _next = _next->next;
    }

    return _next;
}


cart *get_second(cart *head){
    cart *first_item = head;
    cart *second_item = first_item->next;
    return second_item;
}

compare
功能肯定有效,所以我不会在这里发布它。我很确定
get_second
get_end_cart
同样有效。因此,我想我的错误可能是在
交换
排序
中,但我看不出问题出在哪里。

更改交换功能

void swap(cart **ptr1, cart **ptr2){
    cart *temp = *ptr1;
    *ptr1 = *ptr2;
    *ptr2 = temp;
}
您要做的是传递指针并在本地更改其值。您需要传递指针的地址(指向指针的指针)

确保在使用
交换
函数的地方,参数是
购物车
指针的地址

以下是一个片段:

int main(int argc, char **argv) {
    cart *i = (cart *)malloc(sizeof(cart));
    cart *j = (cart *)malloc(sizeof(cart));
    i->item_name = "hello";
    j->item_name =" bla";
    i->next = j;
    printf("i %s\n", i->item_name);
    printf("j %s\n", j->item_name);
    swap(&i, &j);
    printf("i %s\n", i->item_name);
    printf("j %s\n", j->item_name);
}
输出应为:

i hello
j  bla
i  bla
j hello
编辑 但是,在您的情况下,这将不起作用,因为地址已更改,在最坏的情况下,这可能会导致分段错误。 另一种解决方法是交换属性

void swap(cart *ptr1, cart *ptr2){
    char *tmp_name;
    int tmp_quantity;
    tmp_name = ptr1->item_name;
    tmp_quantity = ptr1->quantity;
    ptr1->item_name = ptr2->item_name;
    ptr1->quantity = ptr2->quantity;
    ptr2->item_name = tmp_name;
    ptr2->quantity = tmp_quantity;
}
现在,我们不必处理下一个
,希望一切顺利。我们只是在
i
j
的属性(
item\u name
quantity
)之间交换

因此,代码段应该如下所示:

int main(int argc, char **argv) {
    cart *i = (cart *)malloc(sizeof(cart));
    cart *j = (cart *)malloc(sizeof(cart));
    i->item_name = "hello";
    j->item_name =" bla";
    i->next = j;
    printf("i %s\n", i->item_name);
    printf("j %s\n", j->item_name);
    swap(i, i->next);
    printf("i %s\n", i->item_name);
    printf("j %s\n", j->item_name);
}

塔达!:D

我认为您不必在交换功能中更改购物车的属性。唯一需要的是指向要交换的项之前的元素的指针

void swap(cart **first, cart **ptr1, cart **ptr2){
    (*first)->next = *ptr2;
    (*ptr1)->next = (*ptr2)->next;
    (*ptr2)->next = *ptr1;
}
我认为这是可行的,但我们应该检查一下。如果你这样做交换,注意你的名单上的行乞


如果不必对预制列表进行排序,则应按排序顺序插入项目。

交换功能不起任何作用。它正在交换局部变量。你的交换方法根本不起作用。您需要通过引用传递,然后实际更新到上一个/下一个项目的链接。这会导致以下错误:
警告:从不兼容的指针类型[默认启用]交换(j,j->next)传递“swap”的参数1;^注意:应为“struct cart**”,但参数类型为“struct c art*”无效交换(cart**ptr1,cart**ptr2)是的,没错。您需要将
swap(j,j->next)
更改为
swap(&j,&j->next)
,正如我上面提到的:)嗯,它似乎仍然不起作用。当我试图打印出排序结果时,我得到的似乎是一个无限循环。是的,编译很好,而且我没有遇到任何崩溃或奇怪的行为。除此之外,当我在排序后打印列表时,它将按照与输入相同的顺序打印。因此,似乎根本没有进行排序。另外,我检查并再次检查了我的比较函数-它肯定工作正常,所以不可能是这样。我想可能是因为链接列表的前一项仍然指向原始项(即使在它被交换之后),这就是为什么会发生这种情况。你认为这是正确的吗?因为我试图这样打印:
\u next=node->head;while(_next!=NULL){print;_next=_next->next}