dlinkedlist.h
#ifndef _DLINKED_LIST_H__
#define _DLINKED_LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int ETYPE;
typedef struct DNode{
ETYPE elem;
struct DNode *prev;
struct DNode *next;
}DNode,*DLinkedList;
#define DNODESIZE sizeof(struct DNode)
DLinkedList dlinked_list_create(void);
bool dlinked_list_empty(DLinkedList head);
size_t dlinked_list_size(DLinkedList head);
int dlinked_list_insert(DLinkedList head,size_t pos,ETYPE elem);
int dlinked_list_delete(DLinkedList head,size_t pos,ETYPE *pelem);
int dlinked_list_get(DLinkedList head,size_t pos,ETYPE *pelem);
ETYPE *dlinked_list_index(DLinkedList head,size_t pos);
ETYPE *dlinked_list_find(DLinkedList head,ETYPE *pelem);
void dlinked_list_clear(DLinkedList head);
void dlinked_list_destroy(DLinkedList head);
#endif
dlinkedlist.c
#include "dlinkedlist.h"
static struct DNode *create_dnode(ETYPE elem,struct DNode *prev,struct DNode *next){
struct DNode *node = (struct DNode *)malloc(DNODESIZE);
if(node != NULL){
node->elem = elem;
node->prev = prev;
node->next = next;
}
return node;
}
DLinkedList dlinked_list_create(void){
return create_dnode(0,NULL,NULL);
}
bool dlinked_list_empty(DLinkedList head){
return head->next == NULL;
}
size_t dlinked_list_size(DLinkedList head){
size_t size = 0;
struct DNode *node = head->next;
for(;node!=NULL;node=node->next){
++size;
}
return size;
}
static struct DNode *dlinked_list_get_prev_node(DLinkedList head,size_t pos){
size_t i;
struct DNode *node = head;
for(i=0;i<pos&&node!=NULL;++i){
node = node->next;
}
return node;
}
int dlinked_list_insert(DLinkedList head,size_t pos,ETYPE elem){
struct DNode *prev = dlinked_list_get_prev_node(head,pos);
if(prev == NULL){
return -1;
}
struct DNode *curr = create_dnode(elem,prev,prev->next);
if(curr == NULL){
return -1;
}
if(prev->next != NULL)
prev->next->prev = curr;
prev->next = curr;
return 0;
}
int dlinked_list_delete(DLinkedList head,size_t pos,ETYPE *pelem){
struct DNode *prev = dlinked_list_get_prev_node(head,pos);
if(prev == NULL || prev->next == NULL){
return -1;
}
struct DNode *curr = prev->next;
*pelem = curr->elem;
if(curr->next!=NULL)
curr->next->prev = prev;
prev->next = curr->next;
free(curr);
return 0;
}
int dlinked_list_get(DLinkedList head,size_t pos,ETYPE *pelem){
struct DNode *curr = dlinked_list_get_prev_node(head,pos+1);
if(curr == NULL){
return -1;
}
*pelem = curr->elem;
return 0;
}
ETYPE *dlinked_list_index(DLinkedList head,size_t pos){
struct DNode *curr = dlinked_list_get_prev_node(head,pos+1);
if(curr == NULL){
return NULL;
}
return &curr->elem;
}
ETYPE *dlinked_list_find(DLinkedList head,ETYPE *pelem){
struct DNode *node = head->next;
for(;node!=NULL;node = node->next){
if(node->elem == *pelem){
return &node->elem;
}
}
return NULL;
}
void dlinked_list_clear(DLinkedList head){
struct DNode *node,*next;
for(node=head->next;node!=NULL;node = next){
next = node->next;
free(node);
}
head->next = NULL;
}
void dlinked_list_destroy(DLinkedList head){
dlinked_list_clear(head);
free(head);
}
双向循环
cirdlinkedlist.h
#ifndef _CIR_DLINKED_LIST_H__
#define _CIR_DLINKED_LIST_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct CDNode{
void *pelem;
struct CDNode *prev;
struct CDNode *next;
}CDNode;
typedef struct CDList{
struct CDNode *head;
size_t elemSize;
size_t size;
}*CDLinkedList;
CDLinkedList cdlinked_list_create(size_t elemSize);
bool cdlinked_list_empty(CDLinkedList list);
size_t cdlinked_list_size(CDLinkedList list);
void cdlinked_list_clear(CDLinkedList list);
void cdlinked_list_destroy(CDLinkedList list);
int cdlinked_list_insert(CDLinkedList list,size_t pos,const void *pelem);
int cdlinked_list_push_front(CDLinkedList list,const void *pelem);
int cdlinked_list_push_back(CDLinkedList list,const void *pelem);
int cdlinked_list_delete(CDLinkedList list,size_t pos,void *pelem);
int cdlinked_list_pop_front(CDLinkedList list,void *pelem);
int cdlinked_list_pop_back(CDLinkedList list,void *pelem);
void *cdlinked_list_get(CDLinkedList list,size_t pos);
void *cdlinked_list_find(CDLinkedList list,const void *key,int (*comp)(const void*,const void*));
void *cdlinked_list_find_by_cnt(CDLinkedList list,const void *key,size_t cnt,int (*comp)(const void*,const void*));
#endif
cirdlinkedlist.c
#include "cirdlinkedlist.h"
static struct CDNode *create_cdnode(const void *pelem,struct CDNode *prev,struct CDNode *next){
struct CDNode *node = (struct CDNode *)malloc(sizeof(struct CDNode));
if(node!=NULL){
node->pelem = (void*)pelem;
node->prev = prev;
node->next = next;
}
return node;
}
CDLinkedList cdlinked_list_create(size_t elemSize){
CDLinkedList list = (CDLinkedList)malloc(sizeof(struct CDList));
if(list!=NULL){
list->head = create_cdnode(NULL,NULL,NULL);
if(list->head==NULL){
free(list);
return NULL;
}
}
list->head->prev = list->head;
list->head->next = list->head;
list->elemSize = elemSize;
list->size = 0;
return list;
}
bool cdlinked_list_empty(CDLinkedList list){
return list->head->next == list->head;
}
size_t cdlinked_list_size(CDLinkedList list){
return list->size;
}
void cdlinked_list_clear(CDLinkedList list){
struct CDNode *node = list->head->next;
struct CDNode *next;
for(;node!=list->head;node=next){
next = node->next;
free(node->pelem);
free(node);
}
list->head->next = list->head;
list->head->prev = list->head;
list->size = 0;
}
void cdlinked_list_destroy(CDLinkedList list){
cdlinked_list_clear(list);
free(list->head);
free(list);
}
static struct CDNode *cdlinked_list_get_node(CDLinkedList list,size_t pos){
struct CDNode *node = list->head->next;
size_t i;
for(i=0;i<pos&&node!=list->head;node=node->next,i++);
if(i==pos)
return node;
else
return NULL;
}
int cdlinked_list_insert(CDLinkedList list,size_t pos,const void *pelem){
struct CDNode *curr = cdlinked_list_get_node(list,pos);
if(curr == NULL){
return -1;
}
void *pdata = malloc(list->elemSize);
if(pdata == NULL){
return -2;
}
memcpy(pdata,pelem,list->elemSize);
struct CDNode *node = create_cdnode(pdata,curr->prev,curr);
if(node == NULL){
free(pdata);
return -3;
}
curr->prev->next = node;
curr->prev = node;
list->size++;
return 0;
}
int cdlinked_list_push_front(CDLinkedList list,const void *pelem){
void *pdata = malloc(list->elemSize);
if(pdata == NULL){
return -1;
}
memcpy(pdata,pelem,list->elemSize);
struct CDNode *node = create_cdnode(pdata,list->head,list->head->next);
if(node == NULL){
free(pdata);
return -2;
}
list->head->next->prev = node;
list->head->next = node;
list->size++;
return 0;
}
int cdlinked_list_push_back(CDLinkedList list,const void *pelem){
void *pdata = malloc(list->elemSize);
if(pdata == NULL){
return -1;
}
memcpy(pdata,pelem,list->elemSize);
struct CDNode *node = create_cdnode(pdata,list->head->prev,list->head);
if(node == NULL){
free(pdata);
return -2;
}
list->head->prev->next = node;
list->head->prev = node;
list->size++;
return 0;
}
static void cdlinked_list_delete_node(CDLinkedList list,struct CDNode *node,void *pelem){
memcpy(pelem,node->pelem,list->elemSize);
node->next->prev = node->prev;
node->prev->next = node->next;
free(node->pelem);
free(node);
--list->size;
}
int cdlinked_list_delete(CDLinkedList list,size_t pos,void *pelem){
struct CDNode *curr = cdlinked_list_get_node(list,pos);
if(curr == NULL || curr == list->head){
return -1;
}
cdlinked_list_delete_node(list,curr,pelem);
return 0;
}
int cdlinked_list_pop_front(CDLinkedList list,void *pelem){
if(list->head->next == list->head){
return -1;
}
cdlinked_list_delete_node(list,list->head->next,pelem);
return 0;
}
int cdlinked_list_pop_back(CDLinkedList list,void *pelem){
if(list->head->prev == list->head){
return -1;
}
cdlinked_list_delete_node(list,list->head->prev,pelem);
return 0;
}
void *cdlinked_list_get(CDLinkedList list,size_t pos){
struct CDNode *curr = cdlinked_list_get_node(list,pos);
if(curr == NULL || curr == list->head){
return NULL;
}
return curr->pelem;
}
void *cdlinked_list_find(CDLinkedList list,const void *key,
int (*comp)(const void*,const void*)){
struct CDNode *node = list->head->next;
for(;node != list->head; node = node->next){
if(comp(key,node->pelem)==0){
return node->pelem;
}
}
return NULL;
}
void *cdlinked_list_find_by_cnt(CDLinkedList list,
const void *key,size_t cnt,int (*comp)(const void*,const void*)){
if(cnt == 0)
return NULL;
struct CDNode *node = list->head->next;
for(;node != list->head; node = node->next){
if(comp(key,node->pelem)==0){
if(--cnt == 0)
return node->pelem;
}
}
return NULL;
}