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


你可能感兴趣的:(C语言)