C - Doubly Linked Lists

Introduction

A doubly linked list will allow you to go through a list in either direction.

You can include an extra pointer in each structure to store the address of the previous structure in addition to the pointer to the next.

Demo

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

typedef struct Dog Dog;       // Define Dog as a type name

struct Dog                      // Structure type definition
{
  int age;/* ww w.  ja  v a2 s  .  co  m*/
  int height;
  char name[20];
  char father[20];
  char mother[20];
  Dog *next;                    // Pointer to next structure
  Dog *previous;                // Pointer to previous structure
};

int main(void)
{
  Dog *first = NULL;            // Pointer to first dog
  Dog *current = NULL;          // Pointer to current dog
  Dog *last = NULL;             // Pointer to previous dog

  char test = '\0';               // Test value for ending input

  for (; ; )
  {
    printf_s("Do you want to enter details of a%s dog (Y or N)? ",
      first != NULL ? "nother" : "");
    scanf_s(" %c", &test, sizeof(test));
    if (tolower(test) == 'n')
      break;

    // Allocate memory for each new dog structure
    current = (Dog*)malloc(sizeof(Dog));
    if (first == NULL)
    {
      first = current;            // Set pointer to first dog
      current->previous = NULL;
    }
    else
    {
      last->next = current;       // Set next address for previous dog
      current->previous = last;   // Previous address for current dog
    }
    printf_s("Enter the name of the dog: ");
    scanf_s("%s", current->name, sizeof(current->name));

    printf_s("How old is %s? ", current->name);
    scanf_s("%d", &current->age);

    printf_s("How high is %s ( in hands )? ", current->name);
    scanf_s("%d", &current->height);

    printf_s("Who is %s's father? ", current->name);
    scanf_s("%s", current->father, sizeof(current->father));

    printf_s("Who is %s's mother? ", current->name);
    scanf_s("%s", current->mother, sizeof(current->mother));

    current->next = NULL;         // In case it's the last...
    last = current;               // ...save its address
  }

  // Now tell them what we know.
  printf_s("\n");
  while (current != NULL)          // Output dog data in reverse order
  {
    printf_s("%s is %d years old, %d hands high,",
      current->name, current->age, current->height);
    printf_s(" and has %s and %s as parents.\n", current->father,
      current->mother);
    last = current;               // Save pointer to enable memory to be freed
    current = current->previous;  // current points to previous in list
    free(last);                   // Free memory for the dog we output
    last = NULL;
  }
  first = NULL;
  return 0;
}

Result

The Dog structure is defined as:

struct Dog                      // Structure type definition
{
  ...
  Dog *next;                    // Pointer to next structure
  Dog *previous;                // Pointer to previous structure
};

The Dog structure now contains two pointers: one to point forward in the list, called next, and the other to point backward to the preceding structure, called previous.

This allows the list to be traversed in either direction.

Related Topics