Search code examples
clinked-listreversedoubly-linked-listfunction-definition

Unable to reverse elements in doubly linked list


I am working on double linked list. The elements are printing perfectly in normal order. But I am unable to display them in reverse order. One of the methods I found online is by swapping method. But I want to print them without swapping method. Is there any other possible way by which I can achieve this?

Thanks in advance.

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

typedef struct node
{
  int data;
  struct node *next;
  struct node *prev;
}list;

list *start=NULL;
list *end=NULL;
list *create(list *);
list *display(list *);
list *reverse_display(list *);

int main()
{
  int n;

  printf("1: Create List\n");
  printf("2: Display\n");
  printf("3: Reverse Display\n");

  for(;;)
  {
    printf("Enter choice: ");
    scanf("%d",&n);

    switch(n)
    {
      case 1: start = create(start);
      break;

      case 2: start = display(start);
      break;

      case 3: start = reverse_display(start);
      break;

      default: printf("Wrong Input!!!\n");
      exit(0);
    }
  }
}

list *create(list *start)
{
  int num;
  list *new_node , *ptr;

  printf("Enter the number: ");
  scanf("%d",&num);

  new_node = (list *)malloc(sizeof(list));
  new_node->data = num;

  if(start == NULL)
  {
      new_node->prev = NULL;
      new_node->next = NULL;
      start = new_node;
  }
  else
  {
    ptr = start;
    while(ptr->next != NULL)
      ptr = ptr->next;
    ptr->next = new_node;
    new_node->prev = ptr;
    new_node->next = NULL;
  }
  return start;
}

list *display(list *start)
{
  list *ptr;
  ptr = start;
  printf("\nElements in original order:\n");
  if(start == NULL)
    printf("Empty List!!!\n");
  else
  {
    while(ptr!=NULL)
  {
    printf("%d\n",ptr->data);
    ptr=ptr->next;
  }
  }
  return start;
}

list *reverse_display(list *start)
{
  list *ptr;
  ptr = end;
  printf("\nElements in reverse order\n");
  while(ptr != start->prev)
  {
    printf("%d\n",ptr->data);
    ptr = ptr->prev;
  }
  return start;
}

Solution

  • For starters this prompt

    printf("1: Create List\n");
    

    is confusing because in fact the list is not created in this selection but a new node is appended to the list. I would rename the prompt like "1: Append a Node to the List\n".

    The function create is incorrect because it does not set the pointer end.

    Using your approach the function can be defined the following way.

    list *create( list *start, list **end )
    {
        int num;
    
        printf( "Enter the number: " );
        scanf( "%d",&num );
    
        list *new_node = malloc( sizeof( list ) );
        new_node->data = num;
        new_node->next = NULL;
    
        if ( start == NULL )
        {
            new_node->prev = NULL;
            start = *end = new_node;
        }
        else
        {
            new_node->prev = end;
            *end = ( *end )->next = new_node;
        }
    
        return start;
    }
    

    And the function must be called like

    start = create( start, &end );
    

    In this case the function revrese_display can be defined like

    list * reverse_display( list *end )
    {
        printf("\nElements in reverse order\n");
    
        if ( end != NULL )
        {
            do 
            {
                printf( "%d\n", end->data );
                if ( end->prev != NULL ) end = end->prev;
            } while ( end->prev != NULL ); 
        }
    
        return end; // now end is equal to start
    }
    

    Though there is no great sense to return the pointer start from the function and the both functions , display and reverse_display could have the return type void.

    Also the list itself should be declared as a separate structure that contains two pointers to the start node and ti the end node.