簡單的通用連結串列實現
阿新 • • 發佈:2018-11-03
最近專案需要用到連結串列, 並且是建立三個不同的專用連結串列,為了對程式碼加以簡化,特採用通用連結串列來實現程式碼功能!
本連結串列是在linux下執行的,因此含有部分系統函式。
本人對指標理解較為粗糙,不能保證程式碼正確性,僅作自己總結而用!
程式碼未加封裝,只有簡單的實現函式。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdbool.h> typedef struct listnode { struct listnode *next; struct listnode *prev; void *data; }List; //新建連結串列頭 List *createNode(void) { List *head = (List *)malloc(sizeof(List)); if(NULL == head) { printf("Usage : malloc error !\n"); return NULL; } head->next = head->prev = head; return head; } //尾插法 List *tailInsert(List *head, void *data) { List *node = (List *)malloc(sizeof(List)); if(NULL == node) { printf("Usage : malloc error !\n"); return NULL; } node->data = data; head->prev->next = node; node->prev = head->prev; head->prev = node; node->next = head; return head; } //摧毀連結串列 void destroyList(List **head) { List *tmp = NULL; List *next = NULL; if((*head)->next == *head) { return; } for(tmp=*head; tmp->next!=*head; tmp=next) { next = tmp->next; free(tmp); } *head = NULL; } //按compare函式來檢索連結串列節點 List *searchList(List *head, void *key, bool (*compare)(void *, void *)) { List *ptr = head; while(ptr->next != head) { ptr = ptr->next; if(compare(ptr->data, key)) { return ptr; } } return NULL; } //刪除compare函式檢索到的節點 List *deleteList(List *head, void *key, bool(*compare)(void *, void*)) { List *ptr = head; while(ptr->next != head) { ptr = ptr->next; if(compare(ptr->data, key)) { ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; free(ptr); break; } } return head; } //列印連結串列 void printList(List *head, void (*print)(void *)) { List *ptr = head; while(ptr->next != head) { ptr = ptr->next; print(ptr->data); } } //把連結串列存入檔案 void saveList(List *head, const char *filename, size_t size) { int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0777); if(-1 == fd) { printf("Usage : open error !\n"); return; } List *ptr = head; while(ptr->next != head) { ptr = ptr->next; write(fd, ptr->data, size); } close(fd); destroyList(&head); } //從檔案讀入連結串列 List *readList(const char *filename, size_t size) { int fd, ret; List *head = createNode(); if(access(filename, F_OK) != 0) { close(open(filename, O_CREAT | O_APPEND, 0777)); } fd = open(filename, O_RDONLY); if(-1 == fd) { printf("Usage : open error !\n"); return NULL; } while(1) { void *data; data = malloc(size); ret = read(fd, data, size); if(0 == ret) { break; } tailInsert(head, data); } close(fd); return head; }
簡單測試:
typedef struct action { char name[20]; int id; }action_t; //比較函式 bool compare(void *data, void *key) { action_t *act = (action_t *)data; int id = (int)key; if(act->id == id) { return true; } return false; } //列印函式 void print(void *data) { action_t *act = (action_t *)data; printf("id = %d\t", act->id); printf("name = %s\n", act->name); } int main(void) { char *filename = "action.txt"; action_t test1 = {"zhao", 1}; action_t test2 = {"qian", 2}; action_t test3 = {"yang", 3}; action_t test4 = {"ling", 4}; action_t test5 = {"zhou", 5}; List *head = createNode(); tailInsert(head, (void *)(&test1)); tailInsert(head, (void *)(&test2)); tailInsert(head, (void *)(&test3)); tailInsert(head, (void *)(&test4)); tailInsert(head, (void *)(&test5)); printList(head, print); //存入檔案 saveList(head, filename, sizeof(action_t)); //從檔案讀取 List *list = readList(filename, sizeof(action_t)); if(deleteList(list, (void *)1, compare)) { printf("刪除id為1的節點,成功則列印!\n"); } //檢驗是否刪除成功 printList(list, print); return 0; }