【问题标题】:Singly linked list in c not working when trying to insert node before first element尝试在第一个元素之前插入节点时,c中的单链表不起作用
【发布时间】:2012-01-05 15:39:47
【问题描述】:

在我使用下面的 insertBefore() 函数之前,C 中的单链表实现工作正常。在 insertBefore() 中,当我尝试在第一个元素之前插入节点时,会发生奇怪的事情。我尝试从正确打印列表的 insertBefore() 内部打印列表。但是,当我尝试先返回时,似乎有些不对劲。因为当我尝试打印相同的列表时返回 main 后,它会进入无限循环。重点是,当我尝试打印值 first.next->data 时返回 main 后,它显示的值与 first.data 的值相同。当我尝试在除第一个节点之前的任何其他位置插入节点时,此代码适用于所有其他情况,例如 insertAfter() 甚至 inserBefore()。

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

struct node
{
   int data;
   node *next;
};

void printList(node *);

node * insertFirst(node *first, int x)
{
 node *ptr = (node *)malloc(sizeof(node));
 ptr->data = x;
 ptr->next = NULL;
 first = ptr;
 return first;
}

node *insertAfter(node *first, int x, int k)
{
  node *p = first;
  node *ptr = (node *)malloc(sizeof(node));
  ptr->data = x;

  while(p != NULL)
  {

         if(p->data == k)
                    break;
         p = p->next;       
  }

  if(p == NULL)
      printf("Element not found\n");
  else
  {
     ptr->next = p->next;
     p->next = ptr;
  }
  printList(first);
  return first;
}

node *insertBefore(node *first, int x, int k)
{
  node *ptr = (node *)malloc(sizeof(node));
  ptr->data = x;
  node *p = first, *follow = NULL;
  while(p != NULL)
  {
         if(p->data == k)
                    break;
         follow = p;
         p = p->next;
  }
  if(p == NULL)
      printf("Element not found\n");
  else
  {
     if(p == first)
     {
          ptr->next = first;
          first = ptr;
     }
     else
     {
         ptr->next = p;
         follow->next = ptr;
     }     
  }
  printList(first);
  printf("first->nxt %u", first->next->data);
  return first;

}

void printList(node *first)
{
  node *p = first;
  while(p != NULL)
  {
         printf(" %d",p->data);
         p = p->next;
  }
  printf("\n");
}

main()
{
  struct node first, *p;

  int i, x, y, t=1;

  while(t)
  {
          printf("1:insertFirst 2:insertAfter 3:insertBefore 4:printList 5:exit\n");
          scanf("%d", &i);
          switch(i)
          {
                   case 1:
                        printf("Enter element to be inserted\n");
                        scanf("%d", &x);
                        first = *insertFirst(&first, x);

                        break;
                   case 2:
                        printf("Enter element to be inserted\n");
                        scanf("%d", &x);
                        printf("Enter element after which to insert node\n");
                        scanf("%d", &y);
                        first = *insertAfter(&first, x, y);
                        break;
                   case 3:
                        printf("Enter element to be inserted\n");
                        scanf("%d", &x);
                        printf("Enter element before which to insert node\n");
                        scanf("%d", &y);
                        first = *insertBefore(&first, x, y);
                        printf("first: %d", first.data);  
                        printf("first.nxt %d", first.next->data);

                        printList(&first);                     
                        break;

                   case 4:
                        printf("Linked list:");
                        printList(&first);
                        break;             
                   case 5:
                        t = 0;
                        break;
          }

  }
  getch();
}

【问题讨论】:

    标签: c linked-list


    【解决方案1】:

    我建议将first(在main())转换为指针(node*)并重新访问您执行以下操作的所有地方:

    first = *insertBefore(&first, x, y);
    

    这应该是:

    first = insertBefore(first, x, y);
    

    否则,您将在左右和中间泄漏内存,并造成无限循环的可能性(其中first.next 指向first)。

    您还需要确保first 已正确初始化,并将first.X 的所有用法替换为first-&gt;X

    编辑:考虑以下代码:

    node * insertFirst(node *first, int x)
    {
     node *ptr = (node *)malloc(sizeof(node));
     ...
     return ptr;
    }
    
    struct node first;
    ...
    first = *insertFirst(&first, x);
    

    insertFirst() 的结果被取消引用,返回的结构被复制到first。一旦分配完成执行,malloc()ed 指针就永远丢失了。

    存在影响其他功能的类似内存泄漏。

    【讨论】:

    • 谢谢。有效。但是您能否详细说明“您正在左右泄漏内存”的意思?以及为什么返回main后first.next指向first。因为当我尝试通过先传递从 insertBefore() 函数打印列表时,它确实正确打印了列表。
    【解决方案2】:

    我假设insertFirst 应该在first 之前插入新节点。但是,它不会因为新节点的next 指针应该指向旧的第一个节点。

    试试这个:

    node * insertFirst(node *first, int x)
    {
        node *ptr = (node *)malloc(sizeof(node));
        ptr->data = x;
        ptr->next = first;  /* The old first node is now second first */
        return ptr;  /* Return the new first node */
    }
    

    【讨论】:

      【解决方案3】:

      您之前的插入内容应如下所示。假设您将head 维护为全局并将新节点的head 节点和data 作为参数传递。

      NODE * addfront(NODE *head, int data)
      {
              NODE * newnode = (NODE *) malloc(sizeof(NODE));
              newnode->data = data;
              newnode->next = head;
      
              head = newnode;
              return head;
      }
      

      上面的代码应该使用如下:

      NODE * head = NULL;
      head = addfront(head, 9);
      

      【讨论】:

        猜你喜欢
        • 2021-08-02
        • 2011-12-23
        • 2019-12-11
        • 1970-01-01
        • 1970-01-01
        • 2017-01-18
        • 2021-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多