删除双循环链表中节点的正确方法

时间:2022-02-09 19:57:09

The purpose of this code is to manage insertion and deletion and visualisation. I just want to know if I'm doing everything correctly, let me know if there are more possible ways to do this. This is my first attempt, i didn't follow any tutorial.

此代码的目的是管理插入和删除以及可视化。我只是想知道我是否正确地做了一切,让我知道是否有更多可能的方法来做到这一点。这是我的第一次尝试,我没有按照任何教程。

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



typedef struct Node {
  int n;
  struct Node *next;
  struct Node *prev;

}TNode;
typedef TNode* Node;



void NewNode(Node *pp, int n)
{
  Node temp, last;

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

  temp->n = n;
  temp->next = temp;
  temp->prev = temp;

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

  *pp = temp;

}

void ViewList(Node head)
{
  if(head == NULL)
  {
    return;
  }
  Node node = head->prev;
 do
  {
    printf("Curr: %d\n", node->n);
    node = node->prev;
  }while(node != head->prev);
}

void ReadData(Node * head, int * n)
{
  printf("\nInsert a number:");
  scanf("%d", n);
  NewNode(head, *n);
}

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

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

void Delete(Node * head)
{
  Node del = SearchNode(*head);

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

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,n;
  Node head = NULL;

  do {
    c = Menu();

    switch (c)
    {
      case 1: ReadData(&head, &n); break;
      case 2: ViewList(head); break;
      case 3: Delete(&head); break;
      default: c = 0;
    }

  } while (c != 0);

  return 0;
}

How can i test if this is a real circular doubly linked list and not a simple doubly linked list?

如何测试这是一个真正的循环双向链表而不是简单的双向链表?

1 个解决方案

#1


0  

Your program works fine, the only real bug I detected is in SearchNode: if the element is not present in the list, you enter an infinite loop. Your list is obviously a circular list and therefore you need to check if you have got back to the head in the function, which means that the element you're searching for is not in the list:

您的程序运行正常,我检测到的唯一真正的错误是在SearchNode中:如果列表中没有该元素,则进入无限循环。你的列表显然是一个循环列表,因此你需要检查你是否已经回到函数的头部,这意味着你要搜索的元素不在列表中:

Corrected version:

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

  Node start = head;     // remember where we started

  while (head != NULL)
  {
    if (head->n == d)
    {
      return head;
    }
    head = head->next;

    if (head == start)   // if we are back to where we started
      break;             // the element hasn't been found and we stop the loop
  }

  printf("\nNo Element [%d] Found", d);
  return NULL;
}

There are also some design flaws, that don't prevent the program from working correctly:

还有一些设计缺陷,不会阻止程序正常工作:

One of them is this: The n variable is not used outside ReadData, so it's pointless to declare it in main and pass it's pointer to ReadData.

其中之一是:在变量数据之外不使用n变量,因此在main中声明它并将其指向ReadData传递是没有意义的。

Corrected version:

void ReadData(Node * head)
{
  int n;  // declare n locally
  printf("\nInsert a number:");
  scanf("%d", &n);
  NewNode(head, n);
}

Call it like this: ReadData(&head) and remove int n; from main.

像这样调用它:ReadData(&head)并删除int n;来自主要。

#1


0  

Your program works fine, the only real bug I detected is in SearchNode: if the element is not present in the list, you enter an infinite loop. Your list is obviously a circular list and therefore you need to check if you have got back to the head in the function, which means that the element you're searching for is not in the list:

您的程序运行正常,我检测到的唯一真正的错误是在SearchNode中:如果列表中没有该元素,则进入无限循环。你的列表显然是一个循环列表,因此你需要检查你是否已经回到函数的头部,这意味着你要搜索的元素不在列表中:

Corrected version:

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

  Node start = head;     // remember where we started

  while (head != NULL)
  {
    if (head->n == d)
    {
      return head;
    }
    head = head->next;

    if (head == start)   // if we are back to where we started
      break;             // the element hasn't been found and we stop the loop
  }

  printf("\nNo Element [%d] Found", d);
  return NULL;
}

There are also some design flaws, that don't prevent the program from working correctly:

还有一些设计缺陷,不会阻止程序正常工作:

One of them is this: The n variable is not used outside ReadData, so it's pointless to declare it in main and pass it's pointer to ReadData.

其中之一是:在变量数据之外不使用n变量,因此在main中声明它并将其指向ReadData传递是没有意义的。

Corrected version:

void ReadData(Node * head)
{
  int n;  // declare n locally
  printf("\nInsert a number:");
  scanf("%d", &n);
  NewNode(head, n);
}

Call it like this: ReadData(&head) and remove int n; from main.

像这样调用它:ReadData(&head)并删除int n;来自主要。