【问题标题】:How to delete nodes in a doubly linked list如何删除双向链表中的节点
【发布时间】:2018-10-12 18:00:14
【问题描述】:

我在删除双向链表中的节点时遇到问题,程序崩溃,我无法找出问题所在。你能帮我么? 这是创建新节点、查看它们并删除它们的完整代码。

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

struct Test
{
  int id;
};

typedef struct Node {
  struct Test structure;
  struct Node * next;
  struct Node *prev;

}TNode;
typedef TNode* Node;

void NewNode(struct Test  p, Node *pp)
{
  Node temp;

  temp = (Node)malloc(sizeof(struct Node));

  temp->structure = p;
  temp->next = *pp;
  temp->prev = NULL;

  if(*pp != NULL)
  {
    (*pp)->prev = temp;
  }

  *pp = temp;

}

void ReadStructure(struct Test * p)
{
  printf("\nID:");
  scanf(" %d", &p->id);
}

void ViewList(Node node)
{
  Node temp;
  while(node != NULL)
  {
    temp = node->prev;
    if(node->prev == NULL)
      {
        printf("Prev = NULL\n");
      }
    else
    {
    printf("Prev: %d\n", temp->structure.id);
    }
    printf("Curr: %d\n", node->structure.id);
    node = node->next;
  }
}

void Delete(Node * head, Node del)
{

       if(*head == NULL || del == NULL)
        {
          return;
        }
       if(*head == del)
       {
         *head = del->next;
       }
       if(del->next != NULL)
       {
         del->next->prev = del->prev;
       }
       if(del->prev != NULL)
       {
         del->prev->next = del->next;
       }
       free(del);
       return;

}

int Menu()
{
  int c;

  printf("*** M E N U ***\n"
     "1 - New Node\n"
     "2 - View List\n"
   "3 - Delete\n"
   "0 - Exit\n"
  "\n>> ");
  scanf(" %d", &c);

  return c;
}

int main()
{
  int c;
  struct Test test;
  Node list = NULL;
  Node del = NULL;
  do {
    c = Menu();

    switch (c)
    {
      case 1: ReadStructure(&test);
              NewNode(test, &list); break;
      case 2: ViewList(list); break;
      case 3: printf("\nElement to Delete: ");
              scanf("%d", &del->structure.id);
              Delete(&list, del); break;
      default: c = 0;
    }

  } while (c != 0);

  return 0;
}

我认为问题与 Node del 的 scanf() 有关,但我不确定。当我只是将listlist-&gt;next 作为函数Delete() 的第二个参数传递时,它可以工作。代码一切正常吗?

【问题讨论】:

  • 用gdb运行程序,得到回溯。确保使用调试进行编译(gcc 上的-g)。这会告诉你它崩溃的确切位置。
  • 我做了调试,当我输入要删除的元素并回车时,我得到了分段错误
  • 我不知道它在哪里崩溃,我只是在 gdb 中输入了 run
  • 它是run,然后在崩溃时输入bt。最上面一行显示了它崩溃的位置。

标签: c doubly-linked-list


【解决方案1】:
int main()
{
  ...
  Node del = NULL;
  ...
  scanf("%d", &del->structure.id);

你的程序应该在这里崩溃。您正在取消引用一个空指针。

您可能需要将用户输入读入一个临时的id 变量,然后在列表中搜索匹配项,如果找到,则可以尝试将其删除。

【讨论】:

  • 我试图不将指针设置为 NULL,但它也出错了。我会试试你的方法,看看是否有帮助。
  • 顺便说一句,它改变了算法,所以你的答案有点不完整,我从这个链接学到了原文:geeksforgeeks.org/delete-a-node-in-a-doubly-linked-list
  • 改变算法?你什么意思?您无法删除条目而不知道它在列表中的位置。这意味着您需要搜索它。另一种方法是让用户输入数字 2 并让您删除列表中的第二项......现在 将是算法的变化
  • 在 geeksforgeeks 算法中,他们将一个节点传递给函数 Delete。并且要删除当前节点,他们使用相同的指针。它只是比较两个节点的结构。
  • 重点是,它们传递了一个 valid 指针——一个指向列表中实际节点的指针。我同意,如果您只想测试删除功能的功能,您可以传递任何节点。
【解决方案2】:

好的,我添加了一个搜索要删除的节点的函数,我修改了一些Delete()函数,这是解决方法,谢谢你的建议:

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

struct Test
{
  int id;
};

typedef struct Node {
  struct Test structure;
  struct Node * next;
  struct Node *prev;

}TNode;
typedef TNode* Node;

void NewNode(struct Test  p, Node *pp)
{
  Node temp;

  temp = (Node)malloc(sizeof(struct Node));

  temp->structure = p;
  temp->next = *pp;
  temp->prev = NULL;

  if(*pp != NULL)
  {
    (*pp)->prev = temp;
  }

  *pp = temp;

}

void ReadStructure(struct Test * p)
{
  printf("\nID:");
  scanf(" %d", &p->id);
}

void ViewList(Node node)
{
  Node temp;
  while(node != NULL)
  {
    temp = node->prev;
    if(node->prev == NULL)
      {
        printf("Prev = NULL\n");
      }
    else
    {
    printf("Prev: %d\n", temp->structure.id);
    }
    printf("Curr: %d\n", node->structure.id);
    node = node->next;
  }
}

Node SearchNode(Node head)
{
  int d;
  printf("\nElement to Delete:");
  scanf("%d", &d);

  while(head != NULL)
    {
      if(head->structure.id == d)
        {
          return head;
        }
      head = head->next;
    }
  printf("\nNo Element [%d] Found", d);
  return NULL;
}

void Delete(Node * head, struct Test temp)
{
  Node del = SearchNode(*head);

       if(*head == NULL || del == NULL)
        {
          return;
        }
       if(*head == del)
       {
         *head = del->next;
       }
       if(del->next != NULL)
       {
         del->next->prev = del->prev;
       }
       if(del->prev != NULL)
       {
         del->prev->next = del->next;
       }
       free(del);
       return;

}

int Menu()
{
  int c;

  printf("\n*** M E N U ***\n"
     "1 - New Node\n"
     "2 - View List\n"
   "3 - Delete\n"
   "0 - Exit\n"
  "\n>> ");
  scanf(" %d", &c);

  return c;
}

int main()
{
  int c;
  struct Test test, del;
  Node list = NULL;

  do {
    c = Menu();

    switch (c)
    {
      case 1: ReadStructure(&test);
              NewNode(test, &list); break;
      case 2: ViewList(list); break;
      case 3: Delete(&list, del); break;
      default: c = 0;
    }

  } while (c != 0);

  return 0;
}

【讨论】:

    【解决方案3】:

    del 值是NULL,但是你在删除的时候引用了它。 您需要在列表中搜索给定 id 的节点,然后将其删除。

    【讨论】:

    • 我已经知道了,但是如何在没有传递给函数 Delete() 的指针且不触及算法的情况下删除它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多