/*************************************************************************
> File Name: mylist.h
> Author: zshh0604
> Mail: zshh0604@.com
> Created Time: 2014年05月18日 星期日 12时30分37秒
************************************************************************/
#ifndef MYLLIST_HEAD
#define MYLLIST_HEAD
#define LLIST_FORWARD 1
#define LLIST_BACKWARD 2
#define VERSION 1
//通用型链表的头节点数据结构。
struct llist_node_st
{
struct llist_node_st *prev;
struct llist_node_st *next;
char data[0];
};
//头节点结构体。
typedef struct
{
int size;
struct llist_node_st head;
}LLIST;
typedef int llist_cmp(const void *, const void *);
typedef void llist_op(void *);
LLIST * llist_create(int size);
void llist_destory(LLIST *ptr);
int llist_insert(LLIST *ptr, void *, int );
int llist_delete(LLIST *ptr,const void *, llist_cmp *);
void* llist_find(LLIST *ptr, const void *, llist_cmp *);
void llist_travel(LLIST *ptr, llist_op *);
int llist_fatch(LLIST *ptr,const void *, void *, llist_cmp *);
int llist_getsum(LLIST *ptr);
int llist_save(LLIST *ptr, const char *path);
LLIST* llist_load(const char *path);
#endif
/*************************************************************************
> File Name: myllist.c
> Author: zshh0604
> Mail: zshh0604@.com
> Created Time: 2014年05月18日 星期日 12时30分17秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"myllist.h"
/*
*
* 创建链表
*/
LLIST * llist_create(int size)
{
LLIST *ptr;
ptr = malloc(sizeof(*ptr));<pre name="code" class="cpp">/*************************************************************************
> File Name: mytest.c
> Author: zshh0604
> Mail: zshh0604@.com
> Created Time: 2014年05月18日 星期日 17时04分11秒
************************************************************************/
#include<stdio.h>
#include<string.h>
#include "myllist.h"
/***
* 需要存入数据结构体。
*/
#define NAMESIZE 32
typedef struct student
{
int id;
char name[NAMESIZE];
int score;
}stu;
void stu_op(void *data)
{
stu * d = data;
printf("d->id = %d, d->name = %s, d->score = %d \n" ,d->id,d->name,d->score);
}
int stu_cmp(const void *key, const void *data)
{
stu *stu1 = (stu*)data;
int *k = (int *)key;
return stu1->id - *k;
}
int main()
{
stu tmp;
stu *tmp1;
LLIST *list;
int i = 0;
list = llist_create(sizeof(tmp));
LLIST *list_tmp;
for(i = 0 ; i< 10; i++)
{
tmp.id = i+1;
tmp.score = 100 -i;
snprintf(tmp.name,sizeof(tmp.name),"stu%d",i+1);
llist_insert(list,&tmp,LLIST_FORWARD);
}
llist_travel(list,stu_op);
printf("\n");
int id = 5;
int ret;
int id1 = 10;
int id2 = 6;
int sum;
ret = llist_fatch(list,&id, &tmp, stu_cmp);
if(ret==0)
{
stu_op(&tmp);
}
llist_travel(list, stu_op);
printf("\n");
tmp1 = llist_find(list, &id1,stu_cmp);
printf("\n");
stu_op(tmp1);
llist_delete(list,&id2,stu_cmp);
llist_travel(list, stu_op);
sum =llist_getsum(list);
printf("sum = %d\n", sum);
LLIST *list1;
llist_save(list,"./tmp.bin");
llist_destory(list);
list_tmp = llist_load("./tmp.bin");
printf("_____________________________________\n");
llist_travel(list_tmp,stu_op);
llist_destory(list_tmp);
return 0;
}
</pre><pre name="code" class="cpp">/*************************************************************************
> File Name: myllist.c
> Author: zshh0604
> Mail: zshh0604@.com
> Created Time: 2014年05月18日 星期日 12时30分17秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"myllist.h"
/*
*
* 创建链表
*/
LLIST * llist_create(int size)
{
LLIST *ptr;
ptr = malloc(sizeof(*ptr));
if(ptr==NULL)
{
printf("malloc head error\n");
return NULL;
}
ptr->size = size;
ptr->head.next = ptr->head.prev = &ptr->head;
return ptr;
}
/*
* 销毁链表。
*
*/
void llist_destory(LLIST *ptr)
{
struct llist_node_st *pos;
struct llist_node_st *cur;
for(cur = ptr->head.next; cur != &ptr->head; cur = pos)
{
pos = cur->next;
free(cur);
}
free(ptr);
}
/*
*
* 插入节点
*
*
* */
int llist_insert(LLIST *ptr, void *data, int mode)
{
struct llist_node_st *newnode;
newnode = malloc(sizeof(*newnode) + ptr->size);
if(newnode == NULL)
{
printf("malloc insert newnoe error\n");
return -1;
}
memcpy(newnode->data, data,ptr->size);
if(mode == LLIST_FORWARD)
{
newnode->prev = &ptr->head;
newnode->next = ptr->head.next;
}
else if(mode == LLIST_BACKWARD)
{
newnode->prev = ptr->head.prev;
newnode->next = &ptr->head;
}
newnode->next->prev = newnode;
newnode->prev->next = newnode;
return 0;
}
/*
* 内部查找命令。
*
* */
struct llist_node_st * llist_find__(LLIST *ptr,const void *key,llist_cmp *cmp)
{
struct llist_node_st *cur;
for(cur = ptr->head.next; cur != &ptr->head; cur = cur->next)
{
if(!cmp(key,cur->data))
break;
}
return cur;
}
/*
* 删除节点。
*
* */
int llist_delete(LLIST *ptr, const void *key,llist_cmp *cmp)
{
struct llist_node_st *cur;
cur = llist_find__(ptr, key, cmp);
if(cur == &ptr->head)
{
printf("delete error \n");
return -1;
}
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur);
return 0;
}
/*
*查找数据。
*
*/
void * llist_find(LLIST *ptr,const void *key,llist_cmp* cmp)
{
struct llist_node_st *cur;
cur = llist_find__(ptr, key , cmp);
if(cur==&ptr->head)
{
printf("no find llist_node_st ndoe");
return NULL;
}
return cur->data;
}
/*
* 遍历节点
*/
void llist_travel(LLIST *ptr, llist_op *op)
{
struct llist_node_st *cur;
for(cur = ptr->head.next; cur != &ptr->head; cur = cur->next)
{
op(cur->data);
}
}
/**
* 获取节点。
*
*/
int llist_fatch(LLIST *ptr, const void *key, void *data, llist_cmp *cmp)
{
struct llist_node_st *tmp;
tmp = llist_find__(ptr, key, cmp);
if(tmp == &ptr->head)
{
printf("no fatch node\n");
return -1;
}
memcpy(data, tmp->data, ptr->size);
tmp->next->prev = tmp->prev;
tmp->prev->next = tmp->next;
free(tmp);
}
/*
*获取节点的总个数。
*
* */
int llist_getsum(LLIST *ptr)
{
int sum = 0;
struct llist_node_st *cur;
for(cur = ptr->head.next; cur != &ptr->head; cur = cur->next)
{
++sum;
}
return sum;
}
int llist_insert__(LLIST *ptr,struct llist_node_st *node, int mode)
{
if(node == NULL)
{
printf("malloc insert newnoe error\n");
return -1;
}
if(mode == LLIST_FORWARD)
{
node->prev = &ptr->head;
node->next = ptr->head.next;
}
else if(mode == LLIST_BACKWARD)
{
node->prev = ptr->head.prev;
node->next = &ptr->head;
}
node->next->prev = node;
node->prev->next = node;
return 0;
}
/**
* 保存节点到文件。
*/
int llist_save(LLIST *ptr, const char *path)
{
FILE *fp;
int num;
int ret;
int version;
long offset_self, offset_num, offset_data;
struct llist_node_st *cur;
fp = fopen(path,"w");
printf("bbbbbbbbb");
if(fp == NULL)
{
printf("fopen fail \n");
return 0;
}
version = VERSION;
fwrite(&version,sizeof(version),1,fp); //写入版本号。
offset_self = ftell(fp); //记录存放数据位置的偏移量的开始位置。
fseek(fp, sizeof(offset_data),SEEK_CUR); //跳过数据偏移字节占用的字节数。
fwrite(&ptr->size,sizeof(ptr->size),1, fp);//写入节点数据的大小。
offset_num = ftell(fp); //为了之后能跳转到那个位置。记录下这个位置。
fseek(fp, sizeof(offset_num),SEEK_CUR); //链表节点的个数。
offset_data = ftell(fp); //
// printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
for(cur = ptr->head.next, num = 0; cur != &ptr->head; cur = cur->next, num++)
{
ret = fwrite(cur->data,ptr->size,1, fp);
if(ret == 0)
{
printf("wirte file error\n");
return -1;
}
}
fseek(fp,offset_self,SEEK_SET);
fwrite(&offset_data, sizeof(offset_data),1,fp);
fseek(fp,offset_num, SEEK_SET);
fwrite(&num, sizeof(num),1,fp);
// printf("num = %d\n", num);
fclose(fp);
// printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
return 0;
}
LLIST* llist_load(const char *path)
{
int version;
long offset;
int size;
int num;
int ret =0;
LLIST *list1;
struct llist_node_st *node;
FILE *fp;
fp = fopen(path,"r");
if(fp==NULL)
{
printf("open file fail\n");
return NULL;
}
// list1 = malloc(sizeof(*list1));
// list1->head.next = list1->head.prev = &list1->head;
fread(&version,sizeof(version),1,fp);
fread(&offset,sizeof(offset),1, fp);
fread(&size,sizeof(size),1,fp);
fread(&num, sizeof(num),1,fp);
fseek(fp,offset,SEEK_SET);
list1 = llist_create(size);
printf("!!!!!!!!!!!!!!!!!!!!!\n");
if(list1 == NULL)
{
printf("list NULL");
fclose(fp);
return NULL;
}
char *data;
printf("##########################\n");
data = (char*)malloc(sizeof(size));
for(ret =0 ; ret < num; ret++)
{
// node = malloc(sizeof(*node)+list1->size);
// if(node==NULL){
// printf("dd\n");
// return NULL;
// }
//fread(node->data,list1->size,1,fp);
fread(data,list1->size,1,fp);
llist_insert(list1,data,LLIST_FORWARD);
// node->prev = &list1->head;
// node->next = list1->head.next;
// node->next->prev = node;
// node->prev->next = node;
// printf("#####\n");
}
// printf("888888888\n");
fclose(fp);
// printf("#33333\n");
return list1;
}