#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
C语言---关于链表的各项操作总结-----单向链表
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
4.带头节点的双链表的实现(C语言)
双链表基本运算的代码实现,前插、后插操作
双链表 头结点 插入操作 删除操作 -
单向链表——C语言描述
单向链表:链表是由一系列的节点组成,每个节点包含两个域,指针域和自定义数据类型typedef struct PERSON{
单向链表 数据结构 线性表 C语言 C++ -
C语言实现单向链表
新建一个的头文件stu.h#ifndef _STU_H#define _STU_Htypedef struct _stu{ char sno[5]; //年纪 char name[21]; //姓名 int a
c语言 visual studio c++ #include 头文件 -
单向链表 c语言实现
单链表的增删改查,排序等基本操作
单链表 c基本 操作 -
1868_C语言单向链表的实现
当我们看到链表的应用的时候,通常与与内存的动态分配以及释放结合到一起的。比如说,一个链表提供了
c语言 链表 windows 数据结构 单向链表 -
C语言-----链表的各项操作总结------双向循环链表#include #define vim