【问题标题】:doubly linked list insert at middle双向链表在中间插入
【发布时间】:2014-02-27 13:32:19
【问题描述】:

谁能确定我的代码中发生了什么导致分段错误?请修改/更正错误的部分。

void InsertAtMid (Node *head){

    int num,count=0,i;
    Node *ptr=head;
    Node *newnode=NULL;
    Node *newnode2=head;

    printf("Enter node to be inserted: ");
    scanf("%d", &num);

    if (head==NULL){
            newnode = head;
            newnode=(Node *)malloc(sizeof(Node));
            newnode->x=num;
            newnode->next=NULL;
            newnode->prev=NULL;
    } else {
            ptr=head->next;
            while(ptr->x!=(count/2)){
                ptr=ptr->next;
            }
            newnode->next=ptr->next;
            newnode->prev=ptr;
            ptr->next->prev=newnode;
            ptr->next=newnode;
    }
}

【问题讨论】:

  • 如果 head 的 next 为 null,这不会正常; ptr=head->下一个;而(ptr->x
  • 我应该如何更正它?
  • 只是一个评论;不要将用户界面放在这样的函数中。将其设为insertAtMid(Node *head, int num) 并在调用者的某处设置scanf。它使函数更普遍有用。
  • 如果head 不是NULL,则不能运行此newnode->next,因为newnodeNULL
  • @user3360685 你应该永远保持newnode是一个新分配的。

标签: c list


【解决方案1】:

所以,根据我对您的代码的理解 - 以下应该 [大部分] 工作:

void InsertAtMid (Node **head){
    int num = 0;
    int count = 0
    int advance = 0;
    Node *ptr = *head;
    Node *newnode = NULL;

    printf("Enter node to be inserted: ");
    scanf("%d", &num);

    if (*head == NULL) {
      *head = (Node *)malloc(sizeof(Node));
      ptr = *head;
      ptr->x = num;
      ptr->next = NULL;
      ptr->prev = NULL;
    } else {
      // *** Count the number of items
      ptr = *head;
      while (ptr != NULL) {
         ptr = ptr->next;
         count++;
      }

      // *** Move to the middle of the list
      ptr = *head;
      while (advance < (count/2)){
         ptr = ptr->next;
         advance++;
      }

      // *** Insert the new value
      newnode = (Node *)malloc(sizeof(Node));
      newnode->x = num;
      newnode->next = ptr->next;
      newnode->prev = ptr;
      ptr->next->prev = newnode;
      ptr->next = newnode;
   }
}

以下是我修复的问题:

  • 您在某个时间点为 head 赋值,但由于“head”没有作为引用传入,因此在第一次调用该函数之后,该值不会保持不变。不用说,您需要一个指向节点类型指针的指针。
  • 您从未计算过列表中的项目数。通常“头”指针会存储此信息,并且您会在添加节点时递增,但由于您没有确定它的唯一方法是遍历列表直到找到计数。
  • 您从未为要插入的新节点分配空间,除非您正在初始化头指针。这也是一个问题。

希望对一些人有所帮助。祝你好运!

【讨论】:

    【解决方案2】:
    int num,count=0,i;
    ...
    ptr=head->next;
    while(ptr->x!=(count/2)){
        ptr=ptr->next;
    

    count 被初始化为 0 并且永远不会改变。

    因此,除非您为 x 输入“0”,否则每次循环都会离开列表的末尾。

    【讨论】:

      【解决方案3】:

      测试以解决在什么情况下您的代码段错误。

      你会发现head == NULL 可以正常工作,但如果head 不为空则失败。

      所以你知道你的错误在 else 块的某个地方。

      在调试器中逐步检查正在运行的代码(如果您不知道如何操作,那么学习永远不会太早:每当您使用调试器解决问题时,您都会想“我为什么不早点转向这个问题?” )。

      计算出您预期会发生什么,观察调试器中的变量,当实际值偏离您的预期时,说明原因。

      我不清楚您期望在您的代码中发生什么,但对于一个具有一个节点的列表实际会发生什么:

      • 它将执行ptr=head-&gt;next;——所以ptr现在是NULL
      • 那么对于while 条件,它会尝试取消对ptr-&gt;x 的引用,并且由于ptr 为NULL,它会出现段错误。

      对此的快速解决方法是:

      while(ptr != NULL && ptr->x ....) {
      

      但是您需要考虑这是否是您想要的实际逻辑;一旦你解决了这个问题,你就会遇到其他问题(例如,count 永远不会改变),可以使用调试器以同样的方式解决。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-18
        • 1970-01-01
        • 1970-01-01
        • 2012-09-29
        • 1970-01-01
        • 2013-09-01
        • 2011-07-20
        相关资源
        最近更新 更多