0

我不知道为什么我会出现段错误。基本思想是使用链表以递归方式插入整数。

node* insert(node** head, int integer)
{
    node* temp = malloc(sizeof(node));
    node* temp1;
    node* newNode;

    if(*head == NULL)
    {
        temp->num = integer;
        temp->next = *head;
        *head = temp;
    }
    else if((*head)->num > integer)
    {
        temp = *head;
        temp1 = temp->next; //breaks the link
        temp->next = newNode;   //creates a new node
        newNode->num = integer;  //adds int
        newNode->next = temp1;   //links new node to previously broken node 
        temp1->next = *head; //next node is NULL 
        *head = temp1;  //Makes next node head again
    }

    else
        insert(&((*head)->next), integer);

    return(temp);
}

我在 GDB 中运行了这段代码,它出现了错误,temp1->next = *head但我不明白为什么。我什至放了笔记来帮助自己,但我想它不起作用。有人可以告诉我为什么我会出现段错误吗?谢谢。

4

4 回答 4

3
temp1 = temp->next;

应该是之前

temp = *head;

如果(*head)->num > integer你想在标题中插入整数,那么你的代码会很复杂而且是错误的。你可以这样做:

else if((*head)->num > integer)
    {
        temp->next = *head;
        temp->num = integer;
        *head = temp;
    }

temp = malloc(sizeof(node));

应该只调用到

if(*head == NULL)

并进入

else if((*head)->num > integer)

所以你的最终功能可能是这样的

node* insert(node** head, int integer)
{
    node* temp;

    if(*head == NULL)
    {
        temp = malloc(sizeof(node));
        temp->num = integer;
        temp->next = *head;
        *head = temp;
    }
    else if((*head)->num > integer)
    {
        temp = malloc(sizeof(node));
        temp->next = *head;
        temp->num = integer;
        *head = temp;
    }

    else
        temp = insert(&((*head)->next), integer);

    return(temp);
}

我使用以下方法测试插入功能:

int main (void) {


   node *tmp, *head = NULL;
   insert(&head, 5);
   insert(&head, 7);
   insert(&head, 3);
   insert(&head, 6);
   insert(&head, 4);
   insert(&head, 2);

   for (tmp = head; tmp!=NULL; tmp = tmp->next) {
        printf("tmp->num  %d\n",tmp->num);
   }

}

它成功了!

$ ./test
tmp->num  2
tmp->num  3
tmp->num  4
tmp->num  5
tmp->num  6
tmp->num  7
于 2013-03-18T16:25:56.313 回答
2

所以你第一次经历这个时, head 是空的,你有一个案例。

下一次遍历,head有指针,没有next节点。head->next 为 NULL。

所以当你到达:

temp1 = temp->next; 

那就是将它设置为NULL。当你到达

temp1->next = *head; //next node is NULL 

哇,temp1 为空。没有 temp1->next 之类的东西,它正在寻找一个没有的结构。

编辑:
当你设置temp = *head. 在确定需要内存之前,您可能不应该分配内存。insert()我的意思是,每次数字小于目标时,您都会调用一个新实例。每次通过时,您都会分配一些您实际不使用的内存。您可能想为 分配内存newnode,而不是temp

而且您可能应该使用更好的命名方案。我的意思是,你第二次调用插入时,它不再是头部。integer可能更像是intToInsertor newValuetemp1更像是savedTail。小问题,但它有助于保持正确,这是一个养成的好习惯。

最后,想想当你遍历列表,找到新项目所属的位置,创建一个新节点,将它的->next字段设置为尾部的其余部分并返回时会发生什么。... 怎么办?前一个节点的next值仍然指向它之前的值。您还需要更新该链接。

于 2013-03-18T16:29:09.443 回答
1

假设链表当前只有一个节点。

所以 *head = 某个节点。

*head->下一个 = NULL。

现在让我们看一下代码:

node* insert(node** head, int integer)
{
    node* temp = malloc(sizeof(node));
    node* temp1;
    node* newNode;

    if(*head == NULL)  // condition = false
    {
        temp->num = integer;
        temp->next = *head;
        *head = temp;
    }
    else if((*head)->num > integer)  // let's assume condition = true
    {
        temp = *head;
        temp1 = temp->next; //breaks the link   // temp1 = NULL
        temp->next = newNode;   //creates a new node  // temp1 is not changed
        newNode->num = integer;  //adds int
        newNode->next = temp1;   //links new node to previously broken node 
        temp1->next = *head; //next node is NULL // NULL->next !!!
        *head = temp1;  //Makes next node head again
    }

    else
        insert(&((*head)->next), integer);

    return(temp);
}
于 2013-03-18T16:35:18.237 回答
0
*head = temp1;

应该是之前

temp1->next = *head;
于 2013-03-18T16:27:29.323 回答