双向循环链表

功能描述:头结点包含标准节点数据域的大小,一个标准节点(不包含数据)

其中head指向头结点,普通节点的头结点指向的是头结点的head域

     

 

#ifndef LLIST_H__
#define LLIST_H__

#define LLIST_FORWARD 1
#define LLIST_BACKWARD 2

typedef void llist_op(const void *);  //可以加上const,不允许修改
typedef int llist_cmp(const void *, const void *);

struct llist_node_st
{
	void *data;
	struct llist_node_st *prev;
	struct llist_node_st *next;
};

typedef struct 
{
	int size;
	struct llist_node_st head;
}LLIST;

LLIST * llist_create(int );
int llist_insert(LLIST *,const void *, int);

void llist_show(LLIST *, llist_op*);

void * llist_find(LLIST *, const void *, llist_cmp *);

int llist_delete(LLIST *, const void *key, llist_cmp *); //删除某一个节点

int llist_fetch(LLIST *, const void *key, llist_cmp *, void *data); //删除一个节点,并且返回

void llist_destroy(LLIST *);

#endif

 具体实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "llist.h"


LLIST * llist_create(int size)
{
	LLIST *head;
	head = malloc(sizeof(*head));
	if(head == NULL)
	{
		return NULL;
	}
	head->size = size;
	head->head.data = NULL;
	head->head.next = &head->head;
	head->head.prev = &head->head;
	return head;
}

int llist_insert(LLIST *head, const void *data, int mode)
{
	struct llist_node_st *node;
	node = malloc(sizeof(*node));
	if(node == NULL)
		return -1;
	node->data = malloc(head->size);
	if(node->data == NULL)
		return -2;
	memcpy(node->data, data, head->size);
	if(mode == LLIST_FORWARD)
	{
		node->next = head->head.next;
		node->prev = &head->head;
	}
	else if(mode == LLIST_BACKWARD)
	{
		node->prev = head->head.prev;
		node->next = &head->head;
	}
	else
	{
		return -3;
	}
	
	node->prev->next = node;
	node->next->prev = node;
	return 0;
}

void llist_show(LLIST *head, llist_op * op)
{
	struct llist_node_st *node; 
	for(node = head->head.next; node != &head->head; node = node->next)  //这里少了 &
	{
		op(node->data);
	}
	return ;
}

static struct llist_node_st * find_(LLIST *ptr, const void *key, llist_cmp *op)
{
	struct llist_node_st *cur;
	for(cur = ptr->head.next; cur != &ptr->head; cur = cur->next)
	{
		if(op(key, cur->data))
			break;
	}
	return cur;  
}

void * llist_find(LLIST *ptr, const void *key, llist_cmp *op)
{
	return find_(ptr, key, op)->data; //如果找不到,那么返回是head的data部分,该部分是NULL
}

int llist_delete(LLIST *ptr, const void *key, llist_cmp *cmp) //删除某一个节点
{
	struct llist_node_st *cur;
	
	cur = find_(ptr, key, cmp);
	if(cur == &ptr->head)   //如果找到的是头节点,那么就是证明没有该节点
		return -1;
	cur->next->prev = cur->prev;
	cur->prev->next = cur->next;
	free(cur->data);
	free(cur);
	return 0;
}

int llist_fetch(LLIST *ptr, const void *key, llist_cmp *cmp, void *data) //删除一个节点,并且返回
{
	struct llist_node_st *cur;
	
	cur = find_(ptr, key, cmp);
	if(cur == &ptr->head)
		return -1;
	cur->next->prev = cur->prev;
	cur->prev->next = cur->next;
	
	if(cur-data != NULL)  //判断一下
		memcpy(data, cur->data, ptr->size);
	free(cur->data);
	free(cur);
	return 0;
}

void llist_destroy(LLIST *ptr)
{
	struct llist_node_st *cur;
	struct llist_node_st *next;
	for(cur = ptr->head.next; cur != &ptr->head; cur = next)
	{
		next = cur->next;
		free(cur->data);
		free(cur);
	}
	free(ptr);
}

man.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "llist.h"

#define NAMESIZE 32
struct score_st
{
	int id;
	char name[NAMESIZE];
	int math;
	int chinese;
};

void print(const void *data)
{
	const struct score_st *score = data;
	printf("%d %s %d %d\n", score->id, score->name, score->math, score->chinese);
	return ;
}

int cmp(const void *key, const void *data)
{
	const int *id =  key;
	const struct score_st *score = data;
	if(*id == score->id)
		return 1;
	return 0;
}

int main(int argc, char **argv)
{
	LLIST *head;
	struct score_st tmp;
	int ret;
	int i;
	struct score_st *data;
	
	head = llist_create(sizeof(tmp));
	if(head == NULL)
	{
		fprintf(stderr, "llist_create failure\n");
		exit(1);
	}
	
	for(i=0; i<7; i++)
	{
		tmp.id = i;
		snprintf(tmp.name, NAMESIZE, "stu%d", i);
		tmp.math = rand()%100;
		tmp.chinese = rand()%100;
		ret = llist_insert(head, &tmp, LLIST_BACKWARD);
		if(ret < 0)
		{
			fprintf(stderr, "llist_insert failure\n");
			exit(1);
		}
	}
	
	int id = 2;
	data = llist_find(head, &id, cmp);
	if(data != NULL)
	{
		print(data);
	}
	else
	{
		printf("can not found\n");
	}
	
	printf("\n");
	llist_show(head, print);
	
	printf("\n");
	ret = llist_delete(head, &id, cmp);
	if(ret < 0)
	{
		printf("delete can not found\n");
	}
	llist_show(head, print);
	
	printf("\n");
	struct score_st score;
	id = 3;
	ret = llist_fetch(head, &id, cmp, &score);
	if(ret < 0)
	{
		printf("fetch can not found\n");
	}
	else
		print(&score);
	
	llist_destroy(head);
	exit(1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值