简体   繁体   English

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

[英]Correct way to delete a node in doubly circular linked list

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? 我如何测试这是一个真正的圆形双向链表,而不是一个简单的双向链表?

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. 您的程序运行良好,我检测到的唯一真正的错误是在SearchNode :如果列表中不存在该元素,则进入无限循环。 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: 您的列表显然是一个循环列表,因此您需要检查您是否回到函数的开头,这意味着您要搜索的元素不在列表中:

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 . 其中之一是:在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; 这样调用: ReadData(&head)并删除int n; from main . main

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM