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 *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);
list_node_t *list_locate_prev(list_t * list_p, list_node_t * ref_node_p);
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_print_all(list1);
list_insert_first(list1, 1, 'x');
list_print_all(list1);
list_insert_after_node(list1, list1->list_head, 78, 'y');
list_print_all(list1);
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---------- test list_locate_prev(%d, '%c') ----------\n", p->value, p->c);
list_node_t *prev_node = list_locate_prev(list1, p);
list_print_node(prev_node);
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->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\n", node_p, node_p->value, node_p->c, node_p->next);
}
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;
}
list_node_t *list_locate_prev(list_t * list_p, list_node_t * ref_node_p)
{
list_node_t *p = list_p->list_head;
while (p)
{
if (p->next == ref_node_p)
{
// found!
fprintf(stdout, "%s:%d:%s(%d, '%c'): found!\n", __FILE__, __LINE__, __func__, ref_node_p->value, ref_node_p->c);
break;
}
p = p->next;
}
if (p == NULL)
{
fprintf(stdout, "%s:%d:%s(%d, '%c'): not found!\n", __FILE__, __LINE__, __func__, ref_node_p->value, ref_node_p->c);
}
return p;
}
#if 0
int list_locate_prev_obsolete(list_t * list_p, int value, char c, list_node_t ** location)
{
if (list_p->list_head->value == value && list_p->list_head->c == c)
{
// before list_head
*location = NULL;
return 0;
}
list_node_t *p = list_p->list_head;
while (p->next)
{
if (p->next->value == value && p->next->c == c)
{
//return p;
*location = p;
return 1;
}
p = p->next;
}
*location = NULL;
return 2;
}
#endif
int list_insert_first(list_t * list_p, int value, char c)
{
list_node_t *new_node = list_create_node(value, c);
if (!new_node)
{
// failed
return -1;
}
//------------------------------------------------------------------
// head-+ tail-+
// | |
// v v
// +-----------+ +-----------+
// | data | ---+---> | data | ---+--> NULL
// +-----------+ +-----------+
// ^
// |
// +----------------------+
// |
// +-----------+ |
// new_node --> | data | ---+---+
// +-----------+
//------------------------------------------------------------------
new_node->next = list_p->list_head;
//------------------------------------------------------------------
// head tail-+
// | |
// | v
// | +-----------+ +-----------+
// | | data | ---+---> | data | ---+--> NULL
// | +-----------+ +-----------+
// | ^
// | |
// | +----------------------+
// | |
// +--------->+-----------+ |
// new_node --> | data | ---+---+
// +-----------+
//------------------------------------------------------------------
list_p->list_head = new_node;
if (list_p->list_tail == NULL)
{
list_p->list_tail = new_node;
}
return 0;
}
int list_insert_last(list_t * list_p, int value, char c)
{
if (!list_p->list_tail)
{
// the list is empty
assert(!list_p->list_head);
list_insert_first(list_p, value, c);
assert(list_p->list_head == list_p->list_tail);
}
else
{
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)
{
if (node_p == list_p->list_head)
{
list_insert_first(list_p, value, ch);
}
else
{
list_node_t *prev = list_locate_prev(list_p, node_p);
list_insert_after_node(list_p, prev, value, ch);
}
return 0;
}
int list_insert_after_node(list_t * list_p, list_node_t * node_p, int value, char c)
{
if (node_p == NULL)
{
fprintf(stderr, "Referene node is not exist!\n");
if (!list_p->list_head)
{
list_insert_first(list_p, value, c);
return 0;
}
else
{
return -1;
}
}
// 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;
}
new_node->next = node_p->next;
node_p->next = new_node;
// last node?
if (node_p == list_p->list_tail)
{
list_p->list_tail = 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)
{
fprintf(stdout, "\n\n##### Calling %s:%d:%s() ...\n", __FILE__, __LINE__, __func__);
if (!list_p->list_head)
{
fprintf(stderr, "%s:%d:%s(): Empty list.\n", __FILE__, __LINE__, __func__);
return;
}
list_node_t *node_p = list_p->list_head;
list_p->list_head = list_p->list_head->next;
if (list_p->list_head == NULL)
{
list_p->list_tail = NULL;
}
free(node_p);
fprintf(stdout, "##### Leaving from %s:%d:%s() ...\n\n", __FILE__, __LINE__, __func__);
}
int list_delete_last_node(list_t * list_p)
{
//list_print_all(list_p);
if (!list_p->list_tail)
{
// empty list
assert(!list_p->list_head);
fprintf(stderr, "%s:%d:%s(): Empty list, give up!\n", __FILE__, __LINE__, __func__);
return -1;
}
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 == list_p->list_head)
{
// first node
list_delete_first_node(list_p);
}
else
{
list_node_t *prev_node_p = list_locate_prev(list_p, node_p);
prev_node_p->next = node_p->next;
// last node?
if (list_p->list_tail == node_p)
{
list_p->list_tail = prev_node_p;
}
//fprintf(stdout, "list_tail: %p\n", list_p->list_tail);
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-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);
}
free(list_p);
}
// vim: tabstop=8

浙公网安备 33010602011771号