Как удалить узлы в двусвязном списке - PullRequest
0 голосов
/ 12 октября 2018

У меня проблемы с удалением узлов в двусвязном списке, сбой программы, и я не могу понять проблему.Не могли бы вы мне помочь?Это полный код, который создает новые узлы, просматривает их и удаляет их.

#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;
}

Я думаю, что проблема связана с scanf () для Node del, но я не уверен.Когда я просто передаю list или list->next в качестве второго аргумента функции Delete (), это работает.С кодом все в порядке?

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

значение del равно NULL, но вы ссылаетесь на него при удалении.То, что вам нужно, это найти узел в списке для данного идентификатора, а затем удалить его.

0 голосов
/ 12 октября 2018

Хорошо, я добавил функцию, которая ищет удаляемый узел, и немного изменил функцию 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;
}
0 голосов
/ 12 октября 2018
int main()
{
  ...
  Node del = NULL;
  ...
  scanf("%d", &del->structure.id);

Ваша программа должна аварийно завершить работу здесь.Вы разыменовываете нулевой указатель.

Возможно, вам нужно будет прочитать пользовательский ввод во временную переменную id, затем найти в списке соответствующий элемент, и если вы его найдете, вы можете попытаться удалить его.это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...