C语言链表的各项操作总结双向循环链表

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

#define LIST_DATA_FILENAME	"list.data"

//--------------------------------------------------------------------
// Type definition
//--------------------------------------------------------------------
typedef struct list_node
{
  int value;
  char c;
  // you can define other variables here!
  struct list_node *prev;
  struct list_node *next;
} list_node_t;

typedef struct
{
  list_node_t *list_head;
  list_node_t *list_tail;
} list_t;

//--------------------------------------------------------------------
// Function prototype
//--------------------------------------------------------------------
list_t *create_list(void);
void release_list(list_t * list_p);

list_node_t *list_create_node(int value, char c);
void list_release_node(list_node_t * node_p);

list_node_t *list_locate(list_t * list_p, int value, char c);

int list_insert_before_node(list_t * list_p, list_node_t * node_p, int value, char ch);
int list_insert_after_node(list_t * list_p, list_node_t * p, int value, char c);

int list_insert_first(list_t * list_p, int value, char c);
int list_insert_last(list_t * list_p, int value, char c);

void list_delete_first_node(list_t * list_p);
int list_delete_last_node(list_t * list_p);
int list_delete_node(list_t * list_p, list_node_t * node_p);
int list_delete(list_t * list_p, int value, char c);

void list_print_node(list_node_t * p);
void list_print_all(list_t * list_p);

int list_get_length(list_t * list_p);
void list_modify_node(list_t * list_p, int value, char c, int new_value, char new_c);

int list_save_to_file(list_t * list_p, const char *filename);
int list_load_from_file(list_t * list_p, const char *filename);

void list_make_circle(list_t * list_p);

//--------------------------------------------------------------------
// Main function
//--------------------------------------------------------------------
int main(int argc, char **argv)
{
  list_t *list1 = NULL;

  //------------------------------------------------------------------
  // Create a empty list
  //------------------------------------------------------------------
  list1 = create_list();
  list_print_all(list1);

  //list_insert_after_node(list1, list1->list_head, 77, 'z');
  list_insert_before_node(list1, list1->list_head, 77, 'z');
  list_print_all(list1);

  list_insert_first(list1, 1, 'x');
  list_print_all(list1);

  list_insert_after_node(list1, list1->list_head, 78, 'y');
  list_insert_after_node(list1, list1->list_head, 100, 'a');
  list_print_all(list1);

  list_node_t *p = list_locate(list1, 100, 'a');
  list_print_node(p);

  //------------------------------------------------------------------
  // Insert 2 nodes after node(100, 'a')
  //------------------------------------------------------------------
  list_insert_after_node(list1, p, 101, 'b');
  list_insert_after_node(list1, p, 102, 'c');

  list_print_all(list1);

  fprintf(stdout, "\n---------- insert before node(%d, '%c') ----------\n", p->value, p->c);

  list_insert_before_node(list1, p, 99, 'w');
  list_print_all(list1);

  list_delete_last_node(list1);
  list_delete_last_node(list1);
  list_delete_last_node(list1);
  list_delete_last_node(list1);
  list_delete_last_node(list1);
  list_print_all(list1);

  fprintf(stdout, "\n---------- delete node(%d, '%c') ----------\n", 1, 'x');

  list_delete(list1, 1, 'x');
  list_print_all(list1);

  fprintf(stdout, "\n---------- insert first ----------\n");

  list_insert_first(list1, 2, 'm');	// result: 2, 'm' -> 99, 'w' -> ...
  list_insert_first(list1, 3, 'n');	// result: 3, 'n' -> 2, 'm' -> 99, 'w' -> ...
  list_insert_first(list1, 4, 'o');	// result: 4, 'o' -> 3, 'n' -> 2, 'm' -> ...

  list_print_all(list1);

  fprintf(stdout, "\n---------- insert last ----------\n");

  list_insert_last(list1, 5, 'u');	// result: ... -> 101, 'b' -> 5, 'u' -> NULL
  list_insert_last(list1, 6, 'v');	// result: ... -> 101, 'b' -> 5, 'u' -> 6, 'v' -> NULL
  list_insert_last(list1, 7, 's');	// result: ... -> 101, 'b' -> 5' 'u' -> 6, 'v' -> 7, 's' -> NULL

  list_print_all(list1);

  fprintf(stdout, "\n---------- save & load list ----------\n");

  list_save_to_file(list1, LIST_DATA_FILENAME);

  list_t *list2 = create_list();
  list_load_from_file(list2, LIST_DATA_FILENAME);

  list_print_all(list2);

  fprintf(stdout, "\n---------- release list2 ----------\n");
  release_list(list2);

  fprintf(stdout, "\n---------- release list1 ----------\n");
  release_list(list1);

  fprintf(stdout, "\n---------- finished ----------\n");

  return 0;
}

list_node_t *list_create_node(int value, char c)
{
  list_node_t *p = malloc(sizeof(list_node_t));

  if (!p)
  {
    fprintf(stderr, "Allist_locate memory for new node failed.\n");
    return NULL;
  }

  p->value = value;
  p->c = c;
  p->prev = NULL;
  p->next = NULL;

  return p;
}

void list_release_node(list_node_t * node_p)
{
  if (node_p)
  {
    // free dynamic allocated resources.
    free(node_p);
  }
}

void list_print_node(list_node_t * node_p)
{
  fprintf(stdout, "p: %8p, value = %8d, char = '%4c', next = %8p, prev = %8p\n", node_p, node_p->value, node_p->c, node_p->next, node_p->prev);
}

void list_print_all(list_t * list_p)
{
  fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__);

  fprintf(stdout, "list: %p, list->list_head: %p, list->list_tail: %p\n", list_p, list_p->list_head, list_p->list_tail);

  list_node_t *p;

  p = list_p->list_head;

  while (p)
  {
    //fprintf(stdout, "p: %p, value = %d, char = %c, next = %p\n", p, p->value, p->c, p->next);
    list_print_node(p);

    p = p->next;

    if (p == list_p->list_head)
    {
      break;
    }
  }

  fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__);
}

void list_print_all_another(list_t * list_p)
{
  fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__);

  fprintf(stdout, "list: %p, list->list_head: %p, list->list_tail: %p\n", list_p, list_p->list_head, list_p->list_tail);

  if (!list_p->list_head)
  {
    assert(!list_p->list_tail);
    return;
  }

  list_node_t *p = list_p->list_head;

  while (p != list_p->list_tail)
  {
    //fprintf(stdout, "p: %p, value = %d, char = %c, next = %p\n", p, p->value, p->c, p->next);
    list_print_node(p);

    p = p->next;
  }

  list_print_node(list_p->list_tail);

  fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__);
}

list_node_t *list_locate(list_t * list_p, int value, char c)
{
  list_node_t *p = list_p->list_head;

  while (p)
  {
    if (p->value == value && p->c == c)
    {
      // found it!
      fprintf(stdout, "%s:%d:%s(%d, '%c'): found!\n", __FILE__, __LINE__, __func__, value, c);
      break;
    }

    p = p->next;

    if (p == list_p->list_head)
    {
      p = NULL;
    }
  }

  if (p == NULL)
  {
    fprintf(stdout, "%s:%d:%s(%d, '%c'): not found!\n", __FILE__, __LINE__, __func__, value, c);
  }

  return p;
}

int list_insert_first(list_t * list_p, int value, char c)
{
  list_insert_before_node(list_p, list_p->list_head, value, c);
  return 0;
}

int list_insert_last(list_t * list_p, int value, char c)
{
  list_insert_after_node(list_p, list_p->list_tail, value, c);
  return 0;
}

int list_insert_before_node(list_t * list_p, list_node_t * node_p, int value, char ch)
{
  list_node_t *new_node = list_create_node(value, ch);

  if (!new_node)
  {
    fprintf(stderr, "Create new node failed.\n");
    return -1;
  }

  if (list_p->list_head == NULL)
  {
    list_p->list_head = new_node;
    list_p->list_tail = new_node;

    list_make_circle(list_p);

    return 0;
  }

  new_node->next = node_p;
  new_node->prev = node_p->prev;
  node_p->prev->next = new_node;
  node_p->prev = new_node;

  if (list_p->list_head == node_p)
  {
    list_p->list_head = node_p->prev;
  }

  list_make_circle(list_p);

  return 0;
}

int list_insert_after_node(list_t * list_p, list_node_t * node_p, int value, char c)
{
  // create new_node
  list_node_t *new_node = list_create_node(value, c);

  if (!new_node)
  {
    fprintf(stderr, "Create new list_node object failed.\n");
    return -1;
  }

  if (list_p->list_head == NULL)
  {
    list_p->list_head = new_node;
    list_p->list_tail = new_node;

    list_make_circle(list_p);

    return 0;
  }

  new_node->next = node_p->next;
  new_node->prev = node_p;
  node_p->next->prev = new_node;
  node_p->next = new_node;

  if (node_p == list_p->list_tail)
  {
    list_p->list_tail = node_p->next;
  }

  list_make_circle(list_p);

  return 0;
}

int list_get_length(list_t * list_p)
{
  int length = 0;

  list_node_t *p = list_p->list_head;

  while (p)
  {
    length++;
    p = p->next;

    if (p == list_p->list_head)
    {
      break;
    }
  }

  return length;
}

void list_modify_node(list_t * list_p, int value, char c, int new_value, char new_c)
{
  //list_node_t *list_locate(list_t * list_p, int value, char c);
  list_node_t *node_p = list_locate(list_p, value, c);

  if (node_p)
  {
    node_p->value = new_value;
    node_p->c = new_c;

    fprintf(stdout, "Modify node %p successfully.\n", node_p);
  }
  else
  {
    fprintf(stderr, "Cannot locate node(%d, '%c'), failed.\n", value, c);
  }
}

void list_delete_first_node(list_t * list_p)
{
  list_delete_node(list_p, list_p->list_head);
}

int list_delete_last_node(list_t * list_p)
{
  list_delete_node(list_p, list_p->list_tail);

  return 0;
}

int list_delete(list_t * list_p, int value, char c)
{
  list_node_t *node_p = list_locate(list_p, value, c);

  if (!node_p)
  {
    fprintf(stderr, "%s:%d:%s(): Cannot locate target node(%d, '%c'), give up.\n", __FILE__, __LINE__, __func__, value, c);
    return -1;
  }

  list_delete_node(list_p, node_p);

  return 0;
}

int list_delete_node(list_t * list_p, list_node_t * node_p)
{
  fprintf(stdout, "%s:%d:%s(): deleting node(%d, '%c') ...\n", __FILE__, __LINE__, __func__, node_p->value, node_p->c);

  if (!list_p->list_head)
  {
    assert(!list_p->list_tail);
    fprintf(stdout, "Empty list.\n");
    return -1;
  }

  if (list_p->list_head == list_p->list_tail)
  {
    // only one node
    fprintf(stdout, "Free only node.\n");
    free(node_p);
    list_p->list_head = NULL;
    list_p->list_tail = NULL;
  }

  node_p->prev->next = node_p->next;
  node_p->next->prev = node_p->prev;

  if (node_p == list_p->list_head)
  {
    list_p->list_head = node_p->next;
  }

  if (node_p == list_p->list_tail)
  {
    list_p->list_tail = node_p->prev;
  }

  free(node_p);

  list_make_circle(list_p);

  return 0;
}

//--------------------------------------------------------------------
// save_to_file & load_from_list
//--------------------------------------------------------------------
int list_save_to_file(list_t * list_p, const char *filename)
{
  fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__);

  FILE *fp = fopen(filename, "wb");

  if (fp == NULL)
  {
    fprintf(stderr, "Open data file %s failed: %s\n", filename, strerror(errno));
    return -1;
  }

  list_node_t *p = list_p->list_head;

  while (p)
  {
    //size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE * stream);
    fwrite(p, sizeof(list_node_t), 1, fp);
    p = p->next;

    if (p == list_p->list_head)
    {
      break;
    }
  }

  fflush(fp);
  fclose(fp);

  fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__);

  return 0;
}

int list_load_from_file(list_t * list_p, const char *filename)
{
  fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__);

  FILE *fp = fopen(filename, "rb");

  if (fp == NULL)
  {
    fprintf(stderr, "Open list data file %s failed: %s\n", filename, strerror(errno));
    return -1;
  }

  while (1)
  {
    list_node_t new_node;

    size_t n;

    //size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream);
    n = fread(&new_node, sizeof(list_node_t), 1, fp);

    if (n < 1)
    {
      if (feof(fp))
      {
	// reach end-of-file
	break;
      }
      else
      {
	// error occur
	break;
      }
    }
    else
    {
      list_insert_last(list_p, new_node.value, new_node.c);
    }
  }

  fclose(fp);

  fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__);

  return 0;
}

//--------------------------------------------------------------------
// list management functions
//--------------------------------------------------------------------
list_t *create_list(void)
{
  list_t *p = malloc(sizeof(list_t));

  if (!p)
  {
    fprintf(stderr, "Create new list failed.\n");
    return NULL;
  }

  p->list_head = NULL;
  p->list_tail = NULL;

  return p;
}

void release_list(list_t * list_p)
{
  list_node_t *p = list_p->list_head;

  while (p)
  {
    list_node_t *current = p;
    p = p->next;

    fprintf(stdout, "Release node: ");
    list_print_node(current);
    free(current);

    if (p == list_p->list_head)
    {
      break;
    }
  }

  free(list_p);
}

void list_make_circle(list_t * list_p)
{
  //list_print_all(list_p);
  if (list_p->list_head)
  {
    assert(list_p->list_tail);

    list_p->list_tail->next = list_p->list_head;
    list_p->list_head->prev = list_p->list_tail;
  }
}

// vim: tabstop=8


原文地址:https://www.cnblogs.com/javawebsoa/p/3061630.html