c双向循环链表实现

/*************************************************************************
    > 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;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值