我尝试使用两个函数直接对我在链表中输入的数字进行排序,第一个函数在头部添加元素,第二个包含分割错误,应该利用第一个函数来完成这项工作。
#include <stdio.h>
#include <stdlib.h>
typedef struct cellule
{
int val;
struct cellule *suivant;
} cellule;
typedef struct cellule* liste;
liste insert_tete(liste L,int n)
{
liste p;
p=malloc(sizeof(cellule));
p->val=n;
p->suivant=L;
return p;
}//ok :)
liste insert_croissant(liste L,int n)
{
if(!L)
{
L=insert_tete(L,n);
return L;
}
liste p,q;
for(q=L,p=L; (p!=NULL )&&(n> (p->val)) ; q=p,p=p->suivant); //
p=insert_tete(p,n);
q->suivant=p;
return L;
}
我绝不相信这会修复它,但您的代码中至少有一个错误。
考虑初始化 L的情况,但 n
// p = L, q = L;
// Let L = [val|->...
p=insert_tete(p,n);
// p = [n|->[val|->...
q->suivant=p;
// q = L
// Therefore [val|->[n|->L
// And you've just made your linked list circular.
liste insert_croissant(liste L,int n)
{
if(!L)
{
L=insert_tete(L,n);
return L;
}
在这里我们知道L
不是NULL
liste p,q;
for(q=L,p=L; (p!=NULL )&&(n> (p->val)) ; q=p,p=p->suivant); //
在这里获得合法段错误的唯一方法是p
遵循的指针之一是非 0 指针,它不指向正确分配的struct cellule
,而是指向一些无法访问的内存。然后尝试访问p->val
(或p->suivant
)会导致段错误。
进入这种情况的最常见方法(根据我有限的经验)是忘记将第一个指针初始化为 0。
代码存在一个问题,即列表在某些情况下可能会损坏;很容易使列表进入未正确终止的状态(并且可能从列表中"丢失"节点)。 这种情况可能会导致问题,具体取决于其他代码可能如何操作列表。
如果您尝试在不为空的列表中添加新节点,但新值小于或等于第一个节点的值,则该列表最终将成为包含两个节点的循环列表。位于列表顶部的节点之后的任何节点都将丢失。
发生这种情况是因为在这种情况下,调用insert_tete(p,n)
时,p
和 q
都将指向该节点。insert_tete(p,n)
返回后,p-suivant
和 q
将指向列表开头的节点。 所以当
q->suivant = p;
被执行,列表将是循环的,"额外"节点将丢失。
根据其他操作在列表上的操作方式(特别是删除元素时/方式),您可能会发现自己在suivant
字段中留下了一个悬空指针(这可能会导致段错误),或者最终进入无限循环。
使用指针到指针的简化版本。注意:空列表没有特殊情况。
struct cellule {
int val;
struct cellule *suivant;
};
struct cellule *insert_croissant(struct cellule **LL, int val)
{
struct cellule *p,**pp;
for(pp=LL ; *pp && (*pp)->val < val ; pp = &(*pp)->suivant) {;}
/* When we arrive here, pp points to whatever pointer happens
** to point to our current node.
** - If the list was empty, *pp==NULL
** - if the place to insert happens to be the tail of the list, *p is also NULL
** - in all cases, *pp should be placed after the new node, and the new node's pointer should be assigned to *pp
*/
p = malloc(sizeof *p);
p->val = val;
p->suivant = *pp;
*pp = p;
return *LL;
}