C 带链接列表的冒泡排序

C 带链接列表的冒泡排序,c,linked-list,C,Linked List,我是C级新生,现在学习链接列表。当我对链表进行冒泡排序时,出现段错误,GDB指向函数冒泡(),I=ptr->elem。我不知道这是什么原因。请帮我弄清楚 ` #包括 #包括 #包括 #包括 定义i_轨迹(n)printf(“%s是%d.\n”、#n,(n)) 定义s_轨迹(n)printf(“%s.\n”,#n); typedef结构标记节点 { 内因; 结构标记节点*下一步; }节点*SLINK; 无效节点\轨道(链接列表); 节点*节点生成(作废); 无效初始列表(SLINK*标题,int

我是C级新生,现在学习链接列表。当我对链表进行冒泡排序时,出现段错误,GDB指向函数冒泡(),I=ptr->elem。我不知道这是什么原因。请帮我弄清楚

`

#包括
#包括
#包括
#包括
定义i_轨迹(n)printf(“%s是%d.\n”、#n,(n))
定义s_轨迹(n)printf(“%s.\n”,#n);
typedef结构标记节点
{
内因;
结构标记节点*下一步;
}节点*SLINK;
无效节点\轨道(链接列表);
节点*节点生成(作废);
无效初始列表(SLINK*标题,int len);
SLINK locate\u cur(SLINK list,int target\u elem);
无效插入节点(SLINK*列表、int new元素、int tag元素);
SLINK遍历列表(SLINK列表);
无效列表信息(链接列表、内部节点元素);
无效气泡(SLINK列表);
无效掉期(int*a、int*b);
int main(int argc,char*argv[])
{
内伦;
SLINK list=node_generate();
printf(“输入链接长度的数字。\n”);
scanf(“%d”和“len”);
s_轨道(初始开始);
初始列表(&列表,len);
s_轨道(起始端);
导线测量列表(列表);
气泡(列表);
返回退出成功;
}/*------主功能结束------------*/
NODE*NODE_生成(void)/*生成节点*/
{
NODE*new_NODE=malloc(sizeof(NODE));
if(NULL==新节点)
{
printf(“错误:malloc失败。\n”);
退出(退出失败);
}
memset(新的_节点,0,sizeof(节点));
返回新的_节点;
}
无效插入节点(SLINK*列表、int new元素、int tag元素)
/*插入节点*/
{
NODE*new_NODE=NODE_generate();
节点*cur=*列表;
新建节点->元素=新建元素;
if((int)NULL==标记元素)
{
新建节点->下一步=(*列表)->下一步;
(*list)->next=新的_节点;
}
其他的
{
*列表=定位当前(当前、标记元素);
新建节点->下一步=(*列表)->下一步;
(*list)->next=新的_节点;
}
}
无效初始列表(SLINK*标题,int len)
/*生成一个链表并分配它*/
{
srand((未签名)时间(0));
内因;
对于(int i=0;inext)
{
++节点数;
列表信息(ptr、节点编号);
}
退货清单;
}
无效列表\u信息(链接列表,int节点\u num)
/*用于遍历的_列表()*/
{
如果(1==节点数量%10&&11!=节点数量)
{
printf(“%dst元素是%d.\n”,节点号,列表->元素);
}
else if(2==节点数量%10&&12!=节点数量)
{
printf(“%dnd元素是%d.\n”,node_num,list->elem);
}
else if(3==节点数量%10&&13!=节点数量)
{
printf(“%drd元素是%d.\n”,node_num,list->elem);
}
其他的
{
printf(“第%dth个元素是%d.\n”,节点号,列表->元素);
}
}
SLINK locate\u cur(SLINK list,int target\u elem)
/*定位节点的前一个节点*/
{
节点*prev,*cur;
prev=node_generate();
cur=node_generate();
对于(prev=list,cur=list->next;NULL!=cur&&target\u elem!=cur->elem;prev=cur,cur=cur->next)
;
返回电流;
}
无效节点\轨道(节点*标志)
{
printf(“标志元素为%d.\n”,标志->元素);
}
无效气泡(SLINK列表)/*气泡排序*/
{
s_轨道(气泡_开始);
列表=列表->下一步;
SLINK ptr,割台;
ptr=list;/*GDB指向此处*/
int i=0,j=0;
for(;NULL!=list;list=list->next)
{
for(ptr=list;NULL!=ptr;ptr=ptr->next);
{
j=列表->元素;
i=ptr->elem;
//如果(ptr->elem->list->elem)
如果(i>j)
交换(&(ptr->elem),&(list->elem));
}
}
s_轨道(气泡_端);
}
无效交换(int*a,int*b)
{
*a=(*a)^(*b);
*b=(*a)^(*b);
*a=(*a)^(*b);
}

`在
init\u list()
中的
标记元素的用途非常不清楚。我修改了代码以消除该变量,然后运行它并指定5作为输入值。它给出:

Input a number for length of the link.
5
init_start..
init_end..
The 1st element is 0.
The 2nd element is 12.
The 3rd element is 8.
The 4th element is 99.
The 5th element is 7.
The 6th element is 63.
bubble_start.
Segmentation fault: 11
为什么要求5项时打印6项?重复执行时,第一个元素中的值始终为0(3次重复)

通过如下修改
遍历列表()
可以解决该问题:

SLINK traverse_list(SLINK list)
{
    assert(list != 0); 
    SLINK ptr = list->next;
    for (int node_num = 0; ptr != NULL; ptr = ptr->next)
        list_info(ptr, ++node_num);
    return list;
}
有趣的是,
bubble()
中的代码已经跳过了列表中的第一项

但是,
bubble()
中的内部循环有一个错误:

for (ptr = list; NULL != ptr; ptr = ptr->next);
{
    j = list->elem;
    i = ptr->elem;
//  if (ptr->elem > list->elem)
    if (i > j)
        swap (&(ptr->elem), &(list->elem));
}
如果您将其写为:

for (ptr = list; NULL != ptr; ptr = ptr->next)
    ;
{
    j = list->elem;
    i = ptr->elem;  // When this is executed, ptr == NULL!
    if (i > j)
        swap (&(ptr->elem), &(list->elem));
}
你不要那个分号。修复该问题后,代码运行正常:

Input a number for length of the link.
5
init start.
init end.
The 1st element is 12.
The 2nd element is 19.
The 3rd element is 99.
The 4th element is 92.
The 5th element is 28.
traverse 1 end.
bubble_start.
bubble_end.
sort end.
The 1st element is 99.
The 2nd element is 92.
The 3rd element is 28.
The 4th element is 19.
The 5th element is 12.
traverse 2 end.

显然,诊断打印的设置略有修改,但数据是按降序排序的。它看起来也适用于较大的集合;我尝试了55次,没有崩溃,数据中有一些重复,输出按降序排序。

基于xor的交换是不明智的。开头的
#define
缺少
#
。您可以使用
calloc()
而不是
malloc()
,后跟
memset()
。如果((int)NULL==tag\u elem)
测试很奇怪;但是“tag_elem”的用途充其量也很奇怪,我很难理解它的意义,特别是当从
init_list()
中调用
insert_节点时,它总是“NULL”。感谢您的大力帮助。在你的帮助下,我删除了分号,这是个愚蠢的错误。对于init_list(),因为我不喜欢数字4,所以函数看起来很奇怪,也不清楚。我知道第一个节点的值是0,这不是一个错误,对于原始函数,节点的元素是一个并集,它就像这样:'union{char*s;int n;}',第一个节点是由一个字符串分配的,所以在bubble()中,它被跳过。非常感谢。
Input a number for length of the link.
5
init start.
init end.
The 1st element is 12.
The 2nd element is 19.
The 3rd element is 99.
The 4th element is 92.
The 5th element is 28.
traverse 1 end.
bubble_start.
bubble_end.
sort end.
The 1st element is 99.
The 2nd element is 92.
The 3rd element is 28.
The 4th element is 19.
The 5th element is 12.
traverse 2 end.