双向循环链表

一位叫贾老师写的,没有了联系方式
放在只是方便自己看
若有缘再见
联系删除

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

//功能:安全检查宏
//@x:要检查的变量
//@opt:操作符: ==,<,>
//@y:要检查的值; 	if(NULL == p) {  printf("p is null\n"); return -1; }
//@z:返回值			SYSERR(NULL,==,p,"p is null",-1);
//					if(index < 0) {  printf("index must >= 0",-1); }
//					SYSERR(index,<,0,"index must >= 0",-1);
//
//					如果函数定义是: void fun(int *p);  没有返回值
//					if(NULL == p)
//					{
//						printf("p is null\n");
//						return;
//					}
//					SYSERR(NULL,==,p,"p is null\n",);
#define SYSERR(x,opt,y,message,z)  if(x opt y){printf("%s %d %s :error %s\n",__FILE__,__LINE__,__func__,message);return z;}

/*链表节点定义:*/
typedef struct node
{
	void *data;		//数据指针,链表更通用	
	struct node *before;	//前向指针
	struct node *after;		//后向指针
}node_t;//node_t是struct node的类型别名

//功能:创建链表
//参数:无
//返回值:已创建链表的头节点地址
node_t *create_dlist()
{
	node_t *head =(node_t*)malloc(sizeof(node_t));
	SYSERR(NULL,==,head,"head is null",NULL);
	head->before = head->after = head;
	head->data = NULL;
	
	return head;
}

//功能:向双循环链表头部插入数据
//@head:要插入的链表头节点
//@data:要插入链表的数据
//@size:数据的字节大小
//返回值为插入成功与否: 0表示成功,非0表示失败
int insert_hdlist(node_t *head,void *data,int size)
{	
	SYSERR(NULL,==,head,"head is null",-1);
	SYSERR(NULL,==,data,"data is null",-1);
	node_t*newnode =(node*)malloc(sizeof(node_t));	
	SYSERR(NULL,==,newnode,"malloc is null",-2);
	
	newnode->data =malloc(size);
	SYSERR(NULL,==,newnode->data,"malloc is null",-2);
	memcpy(newnode->data,data,size);
	newnode->before =head;

	newnode->after =head->after;
	head->after->before=newnode;
	head->after=newnode;
	return 0;
}

//功能:向双向循环链表尾部插入数据
int insert_tdlist(node_t *head,void *data,int size)
{
	SYSERR(NULL,==,head,"head is null",-1);
	SYSERR(NULL,==,data,"data is null",-1);
	node_t *newnode = (node_t *)malloc(sizeof(node_t));
	SYSERR(NULL,==,newnode,"malloc error",-2);
	
	newnode->data = malloc(size);
	SYSERR(NULL,==,newnode->data,"malloc error",-2);
	memcpy(newnode->data,data,size);
	newnode->before = head->before;
	newnode->after = head;

	head->before->after = newnode;
	head->before = newnode;
	return 0;
}


int insert_idlist(node_t *head,void *data,int size,int index)
{
	SYSERR(NULL,==,head,"head is null",-1);
	SYSERR(NULL,==,data,"data is null",-1);
	SYSERR(index,<,0,"index must >= 0",-1);
	node_t *before = head;

	int i = 0;
	while((i++ < index) && (before->after != head))
		before = before->after;

	SYSERR(head,==,before->after,"at list end",-2);
	node_t *newnode = (node_t *)malloc(sizeof(node_t));
	SYSERR(NULL,==,newnode,"malloc error",-3);
	newnode->data = malloc(size);

	SYSERR(NULL,==,newnode->data,"malloc error",-3);
	memcpy(newnode->data,data,size);
	newnode->before = before;
	newnode->after = before->after;

	before->after->before = newnode;
	before->after = newnode;
	return 0;
}

//功能:用于遍历显示链表中所有节点的函数
//@head:要显示的链表
//@showfun:显示函数指针,要怎么显示,在调用时必须使用具体的函数名:返回类型必须为void,有1个参数,
//这个参数的类型必须为void *
//typedef void (*showfun_t)(const void *data);			  //显示函数指针类型
//void show_hdlist(node_t *head,showfun_t showfun);
//void show_tdlist(node_t *head,showfun_t showfun);

void show_hdlist(node_t *head,showfun_t showfun)
{
	SYSERR(NULL,==,head,"head is null",);
	node_t *temp = head->after;
	while(temp != head)
	{
		showfun(temp->data);
		temp = temp->after;
	}
	printf("\n");
}


void show_tdlist(node_t *head,showfun_t showfun)
{
	SYSERR(NULL,==,head,"head is null",);
	node_t *temp = head->before;
	while(temp != head)
	{
		showfun(temp->data);
		temp = temp->before;
	}
	printf("\n");
}


//功能:按值从链表中查找某节点
//@head:从哪个链表去查找
//@data:要查找的数据
//@cmpfun:比较函数指针,在调用时必须使用具体的函数名:返回类型必须为int,且有两个参数,
//两个参数必须为void *型
//返回值:如果查找到返回此节点,如果未找到返回NULL;
//typedef int (*cmpfun_t)(void *data1,void *data2); //比较函数指针类型
//node_t *find_vdlist(node_t *head,void *data,cmpfun_t cmpfun);

node_t *find_vdlist(node_t *head,void *data,cmpfun_t cmpfun)
{
	SYSERR(NULL,==,head,"head is null",NULL);
	SYSERR(head,==,head->after,"list is null",NULL);
	SYSERR(NULL,==,data,"data is null",NULL);
	node_t *temp = head->after;

	while(temp != head && temp ->data != NULL)
	{
		if(!cmpfun(temp->data,data))
			return temp;
		temp = temp->after;
	}
	return NULL;
}



node_t *find_idlist(node_t *head,int index)
{
	SYSERR(NULL,==,head,"head is null",NULL);
	SYSERR(head,==,head->after,"list is null",NULL);
	SYSERR(index,<,0,"index must >= 0",NULL);
	node_t *before = head;
	
	int i = 0; 
	while(i++ < index && before->after != head)
		before = before->after;

	SYSERR(head,==,before->after,"at list end",NULL);
	return before->after;
}


//功能:删除第一个数据节点
//@head:要从哪个链表删除
int delete_hdlist(node_t *head)
{
	SYSERR(NULL,==,head,"head is null",-1);
	SYSERR(head,==,head->after,"list is null",-1);
	node_t *temp = head->after;
	head->after = temp->after;
	
	temp->after->before = temp->before;
	free(temp->data);
	free(temp);
	return 0;
}

//功能:删除链表尾部节点
int delete_tdlist(node_t *head)
{
	SYSERR(NULL,==,head,"head is null",-1);
	SYSERR(head,==,head->after,"list is null",-1);
	node_t *temp = head->before;
	temp->after->before = temp->before;
	
	
	temp->before->after = temp->after;
	free(temp->data);
	free(temp);
	return 0;
}


int delete_idlist(node_t *head,int index)
{
	SYSERR(NULL,==,head,"head is null",-1);
	SYSERR(head,==,head->after,"list is null",-1);
	SYSERR(index,<,0,"index must >= 0",-1);
	node_t *before,*current;

	before = head;
	int i = 0;
	while(i++ < index && before->after != head)
		before = before->after;

	SYSERR(head,==,before->after,"at list end",-1);
	current = before->after;
	before->after = current->after;
	current->after->before = current->before;
	
	free(current->data);
	free(current);
	return 0;
}

//功能:按值删除,只会删除指定值第一次出现的节点
//@head:要从哪个链表删除
//@cmpfun:比较函数指针
//返回值:删除成功返回0,失败返回非0值
int delete_vdlist(node_t *head,void *data,cmpfun_t cmpfun)
{
	SYSERR(NULL,==,head,"head is null",-1);
	SYSERR(head,==,head->after,"list is null",-1);
	SYSERR(NULL,==,data,"data is null",-1);
	node_t *temp = head->after;

	while(temp != head)
	{
		if(!cmpfun(temp->data,data))
		{
			temp->before->after = temp->after;
			temp->after->before = temp->before;
			free(temp->data);
			free(temp);
			return 0;
		}
		temp = temp->after;
	}
	return -1;
}


//功能:销毁链表,销毁后head为NULL
//返回值:销毁成功返回0,失败返回非0值
int destroy_dlist(node_t **head)
{
	SYSERR(NULL,==,*head,"head is null",-1);
	node_t *current,*after;
	current = after = (*head)->after;
	while(current != *head)
	{
		after = current->after;
		free(current->data);
		free(current);
		current = after;
	}
	
	free(*head);
	*head = NULL;
	return 0;
}

//链表长度
int length_dlist(node_t *head)
{
	SYSERR(NULL,==,head,"head is null",-1);
	node_t *temp = head->after;
	int i = 0;
	
	while(temp != head)
	{
		i++;
		temp = temp->after;
	}
	return i;
}

//功能:对链表按指定方式排序(升序)
//@head:对哪个链表进行排序,
//@cmpfun:比较函数指针,排序的方式,函数指针
//返回值:排序成功返回0,失败返回非0值
int maopao_sortdlist(node_t *head,cmpfun_t cmpfun)
{
	SYSERR(NULL,==,head,"head is null",-1);
	node_t *inext,*jnext;
	void *temp = NULL;
	int flag;

	for(inext = head->after; inext != head; inext = inext->after)
	{
		flag = 0;
		for(jnext = head->after; jnext->after != head; jnext = jnext->after)
		{
			if(cmpfun(jnext->data,jnext->after->data) > 0)
			{
				temp = jnext->data;
				jnext->data = jnext->after->data;
				jnext->after->data = temp;
				flag = 1;		
			}
		}
		if(!flag)
			break;
	}
	return 0;
}

//降序
int maopao1_sortdlist(node_t *head,cmpfun_t cmpfun)
{
	SYSERR(NULL,==,head,"head is null",-1);
	node_t *inext,*jnext;
	void *temp = NULL;
	int flag;

	for(inext = head->after; inext != head; inext = inext->after)
	{
		flag = 0;
		for(jnext = head->after; jnext->after != head; jnext = jnext->after)
		{
			if(cmpfun(jnext->data,jnext->after->data) < 0)
			{
				temp = jnext->data;
				jnext->data = jnext->after->data;
				jnext->after->data = temp;
				flag = 1;		
			}
		}
		if(!flag)
			break;
	}
	return 0;
}




/*

//typedef int (*cmpfun_t)(void *data1,void *data2); //比较函数指针类型

例子:
int cmpcid(void *data1,void *data2)
{
	const stu_t *stu1 = (const stu_t *)data1;
	const stu_t *stu2 = (const stu_t *)data2;
	return stu1->cid - stu2->cid;
	
}
int cmpname(void *data1,void *data2)
{
	const stu_t *stu1 = (const stu_t *)data1;
	const stu_t *stu2 = (const stu_t *)data2;
	return strcmp(stu1->name,stu2->name);
	
}


*/










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值