【问题标题】:Sorted Insertion in linked list with pointers, C program crashes带指针的链表中的排序插入,C程序崩溃
【发布时间】:2018-11-03 14:58:40
【问题描述】:

我正在从一种伪 Pascal 语言“翻译”这个程序。最近我学习了 C 结构和指针的特性,从一开始我就注意到指针很烦人。所以这是链表算法中排序插入的递归版本,它仍然给我带来问题,比如崩溃。

typedef struct node Node;

struct node
{
  int info;
  struct node *link;
};

void ordered_insert_rec(Node *head, Node *new_node)
{
  if(!head)
  {
    new_node->link = head;
    head = new_node;
  }

  if(new_node->info < head->info)
  {
    new_node->link = head;
    head = new_node;
  }
  else
  {
    ordered_insert_rec(head->link, new_node);
  }

这是主要的:

int main()
{
  Node head;
  Node node;
  Node node2;
  Node inserting_node;

  head.info = 1;
  head.link = &node;

  node.info = 3;
  node.link = &node2;

  node2.info = 7;

  inserting_node.info = 5;

  ordered_insert_rec(&head, &inserting_node);

  Node *front = &head;
  while(front)
  {
    printf("%d ", front->info);
    front = front->link;
    if(!front)
    {
      exit(1);
    }
  }
}

也许我在算法末尾打印的列表有问题,是吗?在提示中,输出为“1 3 7”,但程序在一段时间后崩溃。它必须是“1 3 5 7”,通过这种方式我注意到过程“ordered_insert_rec”不能正常工作。

感谢您的帮助。 :)

【问题讨论】:

  • 一个重要的问题是您还需要将node2.link=0; 添加到您的代码中。你崩溃是因为你访问了无效的地址。
  • order_insert_rec 逻辑应该是if()...else if()....else。看看现在发生了什么!
  • node2.linkinserting_node.link未初始化:未定义的行为。

标签: c sorting pointers linked-list crash


【解决方案1】:

这里是更正的代码:

#include <stdio.h>

typedef struct node Node;

struct node
{
  int info;
  struct node *link;
};

void ordered_insert_rec(Node **head, Node *new_node)
{
  // You are inserting at head. So you need to update head pointer.
  // If you don't use double pointers, you only change it locally.
  if(!(*head))
  {
    new_node->link = *head;
    *head = new_node;
    return;
  }

  if(new_node->info < (*head)->info)
  {
    new_node->link = *head;
    *head = new_node;
  }
  else
  {
    ordered_insert_rec(&((*head)->link), new_node);
  }
}

int main()
{
  Node head;
  Node node;
  Node node2;
  Node inserting_node;

  head.info = 1;
  head.link = &node;

  node.info = 3;
  node.link = &node2;

  node2.info = 7;
  node2.link = 0;

  inserting_node.info = 5;
  inserting_node.link = 0;

  Node * start = &head;

  ordered_insert_rec(&start, &inserting_node);

  Node *front = &head;
  while(front)
  {
    printf("%d ", front->info);
    front = front->link;
  }

  return 0;
}

我没有改进您的代码,只是将其更改为作为指针教程的工作代码。你可以把这段代码写得更好。

问题:

  1. 未初始化的链接(headinsertion_node)。
  2. 您的代码在函数中更新head,该函数是一个指针。所以你需要使用双指针,否则你只会在函数中改变它,结果不会发送回main
  3. while 循环内的中断用于打印列表是无用的。 while 的条件在下一次迭代中不会满足,它将停止。
  4. 您在插入空列表时错过了return
  5. 一般来说,人们不使用堆栈变量作为列表成员。通常你需要分配它们。但在这种特定情况下,您可以使用它。

【讨论】:

  • 我把这个 break 放在了 while 中,以检查问题是否是 while 条件。但是感谢您的帮助,您的回答挽救了我的一天!双指针功能,这对我来说是个新闻! :D
  • @RalphTheCreator 双指针用于从函数内部更改指针。正如我所说,我更改了您的代码。实际上,您不需要双指针。作为家庭作业,尝试在没有任何双指针的情况下编写它。 :D
  • 好的,我要写一个非递归版本的算法,我会在那里尝试。即兴回答:我应该创建另一个指针(作为堆栈变量),指向列表元素指针的地址(在我的例子中是 *head)。下次我将在堆栈变量和列表元素之间做出区别。谢谢:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-20
  • 2014-02-18
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多