最近项目需要用到链表, 并且是建立三个不同的专用链表,为了对代码加以简化,特采用通用链表来实现代码功能!
本链表是在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;
}