【数据结构】双向链表

//数据结构C语言双向链表实现
#ifndef __LIST_H__
#define __LIST_H__

#include <stdlib.h>

#define LIST_ITER_FORWARD 0
#define LIST_ITER_REVERSE 1

#define ListHead(l)         ((l)->head)
#define ListTail(l)         ((l)->tail)
#define ListLength(l)       ((l)->length)
#define ListIsEmpty(l)      (ListLength(l)==0)

#define ListPrevNode(n)     ((n)->prev)
#define ListNextNode(n)     ((n)->next)
#define ListNodeValue(n)    ((n)->value)

#define ListSetCopy(l,f)    ((l)->copy = (f))
#define ListSetFree(l,f)    ((l)->free = (f))
#define ListSetMatch(l,f)   ((l)->match = (f))
#define ListSetCompare(l,f) ((l)->compare = (f))

#define ListGetCopy(l)      ((l)->copy)
#define ListGetFree(l)      ((l)->free)
#define ListGetMatch(l)     ((l)->match)
#define ListGetCompare(l)   ((l)->compare)

typedef struct ListNode
{
	struct ListNode * prev;
	struct ListNode * next;
	void     * value;
}ListNode;

typedef struct List
{
	struct ListNode * head;
	struct ListNode * tail;
	unsigned long     length;

	void *(*copy)(void * value);
	void (*free)(void ** value);
	int (*match)(void * value, void * key);	
	int (*compare)(void * value1, void * value2);	
}List;

typedef struct ListIter
{
	struct ListNode * node;
	int direction;
}ListIter;

List * ListCreate(void);

void   ListRelease(List ** list);   //O(n)

void   ListClear(List * list);      //O(n)

List * ListPushFront(List * list, void * value);  //O(1)

List * ListPushBack(List * list, void * value);   //O(1)

ListIter ListGetIterator(List * list, int direction);

ListNode * ListNext(ListIter * iter);             //O(1)

ListNode * ListIndex(List * list, int index);     //O(n)

ListNode * ListSearchNode(List * list, void * key); //O(n)

List * ListInsertNode(List * list, ListNode * oldnode, void * value, int after); //O(1)

void   ListDeleteNode(List * list, ListNode * oldnode); //O(1)

List * ListMerge(List * l, List * o); //O(1)

List * ListRotate(List * list);       //O(1)

List * ListReverse(List * list);      //O(n)

List * ListCopy(List * list);         //O(n)

List * ListSort(List * list);         //O(n)~O(n2)

void   ListSwap(List * l, List * o);  //O(1)

#endif
#include "List.h"

List * ListCreate(void)
{
	List * list = (List*)malloc(sizeof(List));

	if (!list) return NULL;

	list->head = list->tail = NULL;

	list->copy  = NULL;
	list->free  = NULL;
	list->match = NULL;
	list->compare = NULL;

	list->length = 0;

	return list;
}

void ListRelease(List ** list)
{
	if (*list)
	{
		ListClear(*list);
		free(*list);
		*list = NULL;
	}	

	return;
}

void ListClear(List * list)
{
	ListNode * current = list->head;
	ListNode * next = NULL;

	while (current)
	{
		next = current->next;
		if (list->free) list->free(&current->value);		
		free(current);
		current = next;
	}

	list->head = list->tail = NULL;
	list->length = 0;

	return;
}

List * ListPushFront(List * list, void * value)
{
	ListNode * node = (ListNode*)malloc(sizeof(ListNode));

	if (!node) return NULL;

	node->value = value;

	if (list->length == 0)
	{
		node->prev = node->next = NULL;
		list->head = list->tail = node;
	}
	else
	{
		node->prev = NULL;	
		node->next = list->head;
		list->head->prev = node;
		list->head = node;
	}
	
	list->length++;

	return list;
}

List * ListPushBack(List * list, void * value)
{
	ListNode * node = (ListNode*)malloc(sizeof(ListNode));

	if (!node) return NULL;

	node->value = value;

	if (list->length == 0)
	{
		node->prev = node->next = NULL;
		list->head = list->tail = node;
	}
	else
	{
		node->prev = list->tail;
		node->next = NULL;
		list->tail->next = node;
		list->tail = node;
	}

	list->length++;

	return list;
}

ListIter ListGetIterator(List * list, int direction)
{
	ListIter iter;

	if (direction == LIST_ITER_FORWARD)
	{
		iter.node = list->head;
		iter.direction = direction;
	}
	else
	{
		iter.node = list->tail;
		iter.direction = direction;
	}

	return iter;
}

ListNode * ListNext(ListIter * iter)
{
	ListNode * current = iter->node;

	if (current)
	{
		if (iter->direction == LIST_ITER_FORWARD)
		{
			iter->node = current->next;
		}
		else
		{
			iter->node = current->prev;
		}
	}

	return current;
}

ListNode * ListSearchNode(List * list, void * key)
{
	ListIter iter = ListGetIterator(list,LIST_ITER_FORWARD);

	ListNode * node = NULL;

	while((node = ListNext(&iter)) != NULL)
	{
		if (list->match)
		{
			if (list->match(node->value, key))
			{
				return node;
			}
		}
		else
		{
			if (node->value == key)
			{
				return node;
			}
		}
	}

	return NULL;
}

ListNode * ListIndex(List * list, int index)
{
	ListNode * current = NULL;

	if (index >= 0)
	{
		current = list->head;

		while(index-- && current)
		{
			current = current->next;
		}
	}
	else
	{
		current = list->tail;

		index = (-index)-1;

		while(index-- && current)
		{
			current = current->prev;
		}
	}	

	return current;
}

List * ListInsertNode(List * list, ListNode * oldnode, void * value, int after)
{
	ListNode * node = (ListNode*)malloc(sizeof(ListNode));

	if (!node) return NULL;

	node->value = value;

	if (after)
	{
		node->prev = oldnode;
		node->next = oldnode->next;

		if (list->tail == oldnode)
		{
			list->tail = node;
		}
	}
	else
	{
		node->prev = oldnode->prev;
		node->next = oldnode;

		if (list->head == oldnode)
		{
			list->head = node;
		}
	}

	if (node->prev)
	{
		node->prev->next = node;
	}

	if (node->next)
	{
		node->next->prev = node;
	}

	list->length++;

	return list;
}

void ListDeleteNode(List * list, ListNode * node)
{
	if (node->prev)
	{
		node->prev->next = node->next;
	}
	else
	{
		list->head = node->next;
	}

	if (node->next)
	{
		node->next->prev = node->prev;
	}
	else
	{
		list->tail = node->prev;
	}

	if (list->free) list->free(&node->value);

	free(node);
	
	list->length--;

	return;
}

List * ListMerge(List * l, List * o)
{
	if (!o->tail)
	{
		return l;	
	}

	if (!l->tail)
	{
		l->head = o->head;
		l->tail = o->tail;
		l->length = o->length;

		return l;
	}
		
	l->tail->next = o->head;
	o->head->prev = l->tail;
	l->tail = o->tail;	

	l->length += o->length;

	o->head = o->tail = NULL;
	o->length = 0;

	return l;
}

List * ListRotate(List * list)
{
	ListNode * tail = list->tail;

	if (ListLength(list) <= 1) return list;

	list->tail = tail->prev;
	list->tail->next = NULL;

	list->head->prev = tail;
	tail->prev = NULL;
	tail->next = list->head;
	list->head = tail;

	return list;
}

List * ListReverse(List * list)
{
	if (ListLength(list) <= 1)
	{
		return list;
	}

	ListNode * current = list->head;
	ListNode * next    = NULL;
	ListNode * tmp     = NULL;

    while(current)
	{
		next = current->next;
		
		tmp = current->prev;
		current->prev = current->next;
		current->next = tmp;

		current = next;
	}

	tmp = list->head;
	list->head = list->tail;
	list->tail = tmp;

	return list;
}

List * ListCopy(List * list)
{
	List * copy = ListCreate();

	if (copy == NULL) return NULL;

	copy->copy = list->copy;
	copy->free = list->free;
	copy->match = list->match;
	copy->compare = list->compare;

	ListNode * current = NULL;

	ListIter iter = ListGetIterator(list, LIST_ITER_FORWARD);

	while ((current = ListNext(&iter)) != NULL)
	{
		void * value;

		if (copy->copy)
		{
			value = copy->copy(current->value);
			if (!value)
			{
				ListRelease(&copy);
				return NULL;
			}
		}
		else
		{
			value = current->value;
		}

		if (ListPushBack(copy,value) == NULL)
		{
			ListRelease(&copy);
			return NULL;
		}
	}

	return copy;
}

List * ListSort(List * list)
{
	void * tmp = NULL;
	int n = list->length;

	for (int j=0; j<n-1; j++)
	{
		for (int i=0; i<n-j-1; i++)
		{
			ListNode * n1 = ListIndex(list,i);
			ListNode * n2 = ListIndex(list,i+1);

			if (list->compare)
			{
				if (list->compare(n1->value, n2->value) > 0)
				{
					tmp = n1->value;
					n1->value = n2->value;
					n2->value = tmp;
				}
			}
			else
			{
				if (n1->value > n2->value)
				{
					tmp = n1->value;
					n1->value = n2->value;
					n2->value = tmp;
				}
			}
		}
	}

	return list;
}

void   ListSwap(List * l, List * o)
{
	ListNode * head = l->head;
	ListNode * tail = l->tail;
	int length = l->length;

	void *(*pcopy)(void * value) = l->copy;
	void (*free)(void ** value) = l->free;
	int (*match)(void * value, void * key) = l->match;	
	int (*compare)(void * value1, void * value2) = l->compare;	

	l->head = o->head;
	l->tail = o->tail;
	l->length = o->length;

	l->copy = o->copy;
	l->free = o->free;
	l->match = o->match;
	l->compare = o->compare;

	o->head = head;
	o->tail = tail;
	o->length = length;

	o->copy = pcopy;
	o->free = free;
	o->match = match;
	o->compare = compare;
}

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include "List.h"

typedef struct USER
{
	char usrname[20];
	char password[20];
	int  type;
}USER;

void UserInit(USER * usr, const char * name, const char* pwd, int type)
{
	memset(usr, 0, sizeof(USER));
	memcpy(usr->usrname, name, strlen(name));
	memcpy(usr->password, pwd, strlen(pwd));
	usr->type = type;
}

void UserFree(void ** value)
{
	delete(*value);	
	*value = NULL;
}

void * UserCopy(void * value)
{
	USER * usr = (USER*)value;
	USER * copy = new USER();
	UserInit(copy, usr->usrname, usr->password, usr->type);

	return copy;
}

int UserMatch(void * value, void * key)
{
	USER *pvalue = (USER*)value;
	USER *pkey = (USER*)key;

	if (strcmp(pvalue->usrname,pkey->usrname) == 0)
	{
		return 1;
	}	
	else
	{
		return 0;
	}	
}

int UserCompare(void * value1, void * value2)
{
	USER *pvalue1 = (USER*)value1;
	USER *pvalue2 = (USER*)value2;

	if (strcmp(pvalue1->usrname,pvalue2->usrname) > 0)
	{
		return 1;
	}
	else if (strcmp(pvalue1->usrname,pvalue2->usrname) < 0)
	{
		return -1;
	}
	else
	{
		return 0;
	}	
}


int main(int argc, char* argv[])
{	
	int count1 = 100000;
	while(count1--)
	{
		USER *usr1 = new USER();
		UserInit(usr1, "1_zhang", "zhang_1", 1);

		USER *usr2 = new USER();
		UserInit(usr2, "2_wang", "wang_2", 2);

		USER *usr3 = new USER();
		UserInit(usr3, "3_li", "li_3", 3);

		USER *usr4 = new USER();
		UserInit(usr4, "4_zhao", "zhao_4", 4);

		List * list1 = ListCreate();
		List * list2 = ListCreate();
		ListIter iter;	
		ListNode * n;	

		ListSetFree(list1, UserFree);
		ListSetCopy(list1, UserCopy);
		ListSetMatch(list1, UserMatch);	
		ListSetCompare(list1, UserCompare);

		ListSetFree(list2, UserFree);
		ListSetCopy(list2, UserCopy);
		ListSetMatch(list2, UserMatch);	
		ListSetCompare(list2, UserCompare);

		ListPushBack(list1, usr1);
		ListPushBack(list1, usr3);
		ListPushBack(list2, usr2);
		ListPushBack(list2, usr4);

		ListSwap(list1,list2);

		ListMerge(list1,list2);

		iter = ListGetIterator(list1, LIST_ITER_FORWARD);
		while((n = ListNext(&iter)) != NULL)
		{
			USER *usr = (USER *)n->value;
			printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
		}

		ListSort(list1);

		ListReverse(list1);

		iter = ListGetIterator(list1, LIST_ITER_FORWARD);
		while((n = ListNext(&iter)) != NULL)
		{
			USER *usr = (USER *)n->value;
			printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
		}	
		
		USER *usr5 = new USER();
		UserInit(usr5, "4_zhao", "zhao_5", 5);

		ListNode * node4 = ListSearchNode(list1, usr5);
		if (node4)
		{
			USER *usr = (USER *)node4->value;
			printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
		}

		delete usr5;

		List * list3 = ListCopy(list1);

		iter = ListGetIterator(list3, LIST_ITER_FORWARD);
		while((n = ListNext(&iter)) != NULL)
		{
			USER *usr = (USER *)n->value;
			printf("usr.name = %s, usr.pwd = %s, usr.type = %d \n", usr->usrname, usr->password, usr->type);
		}

		while (!ListIsEmpty(list3))
		{
			ListNode * curnode = ListTail(list3);

			USER * usr = (USER *)curnode->value;
			ListDeleteNode(list3, curnode);
		}

		ListRelease(&list3);

		ListRelease(&list1);
		ListRelease(&list2);
	}	
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值