1

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
    For removing a node, you don't need to know if it's a circular list or not, just make sure that all pointers are non-null before you dereference them (and remember to *initialize* all pointers to null). – Some programmer dude Oct 16 '18 at 11:59
  • 1
    I don't know if this what you were asking for but I found someone that has seemed to have done this algorithm in github. Maybe this will help give you something to compare too [Circular Double Linked List in C](https://github.com/hasancse91/data-structures/blob/master/Source%20Code/Circular%20Doubly%20Linked%20List%20(Insert%2C%20Delete%2C%20Print).c) – B. Cratty Oct 16 '18 at 12:00
  • 2
    As for the removal itself, I suggest you do it on paper first: Draw some squares (representing nodes) and arrows between them (representing links). Try to figure out a way to "unlink" on paper before attempting to do it with code. And when you start coding, do it in small, small baby steps, testing and debugging between each step. – Some programmer dude Oct 16 '18 at 12:00
  • @Someprogrammerdude that's the way i used to do this – Stefano Raneri Oct 16 '18 at 12:03
  • 1
    Is your question: _"What is the correct way to delete a node in doubly circular linked list?"_ or is it _"How can I test if this is a real circular doubly linked list and not a simple doubly linked list?"_ These are two very different questions. BTW for deleting a node you don't need to know if it's a circular list or not. – Jabberwocky Oct 16 '18 at 12:11
  • 1
    BTW: your hiding pointer types hehind typedefs only add confusion. I'd drop them alltogether. – Jabberwocky Oct 16 '18 at 12:20

1 Answers1

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:

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.

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.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115