C语言----链表的各项操作-----双向链表

来源:互联网 发布:软件企业评估 编辑:程序博客网 时间:2024/05/16 09:55
#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);//--------------------------------------------------------------------// 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;  }  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 == 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;    return 0;  }  new_node->next = node_p;  new_node->prev = node_p->prev;  if (node_p->prev)  {    node_p->prev->next = new_node;  }  else  {    fprintf(stdout, "Insert node before head.\n");    list_p->list_head = new_node;  }  node_p->prev = new_node;  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;    return 0;  }  new_node->next = node_p->next;  new_node->prev = node_p;  if (node_p->next)  {    node_p->next->prev = new_node;  }  else  {    fprintf(stdout, "Insert node after tail.\n");    list_p->list_tail = new_node;  }  node_p->next = new_node;  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;  }  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){  if (node_p->prev)  {    node_p->prev->next = node_p->next;  }  else  {    // first node    list_p->list_head = node_p->next;  }  if (node_p->next)  {    node_p->next->prev = node_p->prev;  }  else  {    // last node    list_p->list_tail = node_p->prev;  }  free(node_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;  }  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-filebreak;      }      else      {// error occurbreak;      }    }    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);  }  free(list_p);}// vim: tabstop=8