C 无法在循环双链接列表中插入元素

C 无法在循环双链接列表中插入元素,c,linked-list,doubly-linked-list,C,Linked List,Doubly Linked List,我无法在此循环双链接列表中插入元素。输入第一个元素时没有任何问题。但是,当我尝试插入第二个元素时,就遇到了一个问题。问题是:程序会自动终止。 我不知道我到底错在哪里。 感谢您的帮助。 提前谢谢 #include<stdio.h> #include<stdlib.h> typedef struct node { int data; struct node *next; struct node *prev; }list; list *start=NULL; l

我无法在此循环双链接列表中插入元素。输入第一个元素时没有任何问题。但是,当我尝试插入第二个元素时,就遇到了一个问题。问题是:程序会自动终止。 我不知道我到底错在哪里。 感谢您的帮助。 提前谢谢

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

typedef struct node
{
  int data;
  struct node *next;
  struct node *prev;
}list;

list *start=NULL;
list *end=NULL;

void insert();
void display();
void reverse_display();

void main()
{
  int n;

  printf("1: Insert Elements\n");
  printf("2: Display\n");
  printf("3: Reverse Display\n");

  for(;;)
  {
    printf("Enter choice: ");
    scanf("%d",&n);

    switch(n)
    {
      case 1: insert();
      break;

      case 2: display();
      break;

      case 3: reverse_display();
      break;

      default: printf("Wrong Input!!!\n");
      exit(0);
    }
  }
}


void insert()
{
  int num;
  list *new_node , *ptr;

  printf("Enter the number: ");
  scanf("%d",&num);

  new_node = (list *)malloc(sizeof(list));
  new_node->data = num;

  if(start == NULL)
  {
      new_node->next = start;
      new_node->prev = end;
      start = new_node;
      end = new_node;
  }
  else
  {
    ptr = start;
    while(ptr->next != start)
      ptr = ptr->next;
    ptr->next = new_node;
    new_node->prev = ptr;
    new_node->next = start;
    start->prev = new_node;
    end = new_node;
  }
}

void display()
{
  list *ptr;
  ptr = start;
  printf("\nElements in original order:\n");
  if(start == NULL)
    printf("Empty List!!!\n");
  else
  {
    while(ptr->next!=start)
  {
    printf("%d\n",ptr->data);
    ptr=ptr->next;
  }
  printf("%d\n",ptr->data);
  }
}

void reverse_display()
{
  list *ptr , *temp;
  ptr = end;
  printf("\nElements in reverse order\n");
  while(ptr->prev!=end)
  {
    printf("%d\n",ptr->data);
    ptr = ptr->prev;
  }
  printf("%d\n",ptr->data);
}

#包括
#包括
类型定义结构节点
{
int数据;
结构节点*下一步;
结构节点*prev;
}名单;
list*start=NULL;
list*end=NULL;
无效插入();
void display();
无效反向显示();
void main()
{
int n;
printf(“1:插入元素\n”);
printf(“2:Display\n”);
printf(“3:反向显示\n”);
对于(;;)
{
printf(“输入选项:”);
scanf(“%d”和“&n”);
开关(n)
{
案例1:插入();
打破
案例2:显示();
打破
案例3:反向显示();
打破
默认值:printf(“输入错误!!!\n”);
出口(0);
}
}
}
空白插入()
{
int-num;
列表*新节点,*ptr;
printf(“输入数字:”);
scanf(“%d”和&num);
新节点=(列表*)malloc(sizeof(列表));
新建_节点->数据=num;
if(start==NULL)
{
新建节点->下一步=开始;
新建节点->上一个=结束;
开始=新的_节点;
结束=新的_节点;
}
其他的
{
ptr=启动;
同时(ptr->next!=开始)
ptr=ptr->next;
ptr->next=新建_节点;
新建_节点->prev=ptr;
新建节点->下一步=开始;
开始->上一步=新建_节点;
结束=新的_节点;
}
}
无效显示()
{
列表*ptr;
ptr=启动;
printf(“\n按原始顺序排列的元素:\n”);
if(start==NULL)
printf(“空列表!!!\n”);
其他的
{
同时(ptr->next!=开始)
{
printf(“%d\n”,ptr->data);
ptr=ptr->next;
}
printf(“%d\n”,ptr->data);
}
}
无效反向显示()
{
列表*ptr,*temp;
ptr=结束;
printf(“\n元素顺序相反\n”);
同时(ptr->prev!=结束)
{
printf(“%d\n”,ptr->data);
ptr=ptr->prev;
}
printf(“%d\n”,ptr->data);
}

在双循环链表中,如果有一个节点,则它是
下一个
上一个
指针应指向自身。在
insert()
中,您正在执行

  if(start == NULL)
  {
      new_node->next = start;
      new_node->prev = end;
     ......
因此,
next
prev
指针最终指向
NULL
,因为
start
end
最初设置为
NULL
。现在,当您在列表中插入另一个元素时,您将访问
NULL
指针

    while(ptr->next != start)
       ptr = ptr->next;
这就是为什么你们要观察程序终止的原因

插入第一个节点时,应正确设置
next
prev
指针。在代码中,只需设置
开始
结束
指针,然后再设置
下一步
修订
,如下所示:

  if(start == NULL)
  {
      start = new_node;
      end = new_node;
      new_node->next = start;
      new_node->prev = end;
  }

其他:

  • 使用
    void
    作为
    main
    函数的返回类型不符合标准。
    main
    函数的返回类型应为
    int
  • 遵循良好的编程实践,始终检查
    malloc
    返回
  • 不要强制转换
    malloc
    返回

在双循环链表中,如果有一个节点,则它是
下一个
上一个
指针应指向自身。在
insert()
中,您正在执行

  if(start == NULL)
  {
      new_node->next = start;
      new_node->prev = end;
     ......
因此,
next
prev
指针最终指向
NULL
,因为
start
end
最初设置为
NULL
。现在,当您在列表中插入另一个元素时,您将访问
NULL
指针

    while(ptr->next != start)
       ptr = ptr->next;
这就是为什么你们要观察程序终止的原因

插入第一个节点时,应正确设置
next
prev
指针。在代码中,只需设置
开始
结束
指针,然后再设置
下一步
修订
,如下所示:

  if(start == NULL)
  {
      start = new_node;
      end = new_node;
      new_node->next = start;
      new_node->prev = end;
  }

其他:

  • 使用
    void
    作为
    main
    函数的返回类型不符合标准。
    main
    函数的返回类型应为
    int
  • 遵循良好的编程实践,始终检查
    malloc
    返回
  • 不要强制转换
    malloc
    返回

在调试器中运行程序。至少它会立即告诉您触发程序终止的确切代码行。你也可以用它逐行逐行地检查代码和程序变量。你的插入逻辑被破坏了(我相当确信这不是唯一的问题,但它仍然被破坏了)。如果start(因此end)为NULL,则新节点应该是自引用的。(即,next和prev都应引用包含它们的节点)。在将开始和结束设置为新节点之前,您的逻辑将next和prev分别设置为start和end。因此,start和end now引用一个next和prev都为null的节点。因此
while(ptr->next!=start)ptr=ptr->next
保证在迭代的第一步之后遵从空指针。同样值得注意的是,如果列表为空,则您的
reverse_display
将调用未定义的行为。请在调试器中运行您的程序。至少它会立即告诉您触发程序终止的确切代码行。你也可以用它逐行逐行地检查代码和程序变量。你的插入逻辑被破坏了(我相当确信这不是唯一的问题,但它仍然被破坏了)。如果start(因此end)为NULL,则新节点应该是自引用的。(即,next和prev都应引用包含它们的节点)。在将开始和结束设置为新节点之前,您的逻辑将next和prev分别设置为start和end。因此,start和end now引用一个next和prev都为null的节点。因此
while(ptr->next!=start)ptr=ptr->next保证在