/*
* Copyright 2014 YU Heng-yang. All rights reserved.
*
* cdlist.c - Circular doubly-linked list.
*
* Modify data to any other types as you like, note also the
* prototypes of interface functions and data compare function.
*
* 2014-7-6 YU Heng-yang.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ALLOC(size) malloc(size)
#define FREE(p) free(p)
typedef struct DList *DList;
struct DList {
int data;
DList prev, next;
};
DList dlist_new(void);
DList dlist_insert(DList dlist, int data);
DList dlist_delete(DList dlist, int data);
DList dlist_find(DList dlist, int data);
DList dlist_destroy(DList dlist);
void dlist_traversal(DList dlist, void (*apply) (DList dlist, void *arg),
void *arg);
void print(DList dlist, void *arg)
{
assert(arg);
printf((char *)arg, dlist->data);
}
int main(int argc, char *argv[])
{
#define N 5
int i, n;
DList dlist = dlist_new();
for (i = 0; i < N; i++) {
scanf("%d", &n);
dlist = dlist_insert(dlist, n);
assert(dlist);
printf("After insert %d: ", n);
dlist_traversal(dlist, print, "%d ");
putchar('\n');
}
for (i = 0; i < N; i++) {
scanf("%d", &n);
assert(dlist);
dlist = dlist_delete(dlist, n);
printf("After delete %d: ", n);
dlist_traversal(dlist, print, "%d ");
putchar('\n');
}
dlist = dlist_destroy(dlist);
assert(dlist == NULL);
dlist_traversal(dlist, print, "");
assert(dlist == dlist_destroy(dlist));
return 0;
}
DList dlist_new(void)
{
return NULL;
}
DList dlist_insert(DList dlist, int data)
{
DList dl = ALLOC(sizeof(*dl));
assert(dl);
dl->data = data;
if (NULL == dlist)
dl->prev = dl->next = dl;
else { /* head insert */
dl->next = dlist;
dlist->prev->next = dl;
dl->prev = dlist->prev;
dlist->prev = dl;
}
return dlist = dl;
}
DList dlist_delete(DList dlist, int data)
{
DList p = dlist_find(dlist, data);
if (p) {
if (p->next == p) { /* the last element? */
FREE(p);
dlist = NULL;
} else {
if (p == dlist) /* head element? */
dlist = dlist->next;
p->prev->next = p->next;
p->next->prev = p->prev;
FREE(p);
}
}
return dlist;
}
DList dlist_find(DList dlist, int data)
{
DList p;
for (p = dlist; p; p = p->next)
if (p->data == data || p->next == dlist)
break;
return p->data == data ? p : NULL;
}
DList dlist_destroy(DList dlist)
{
DList p, q;
for (p = dlist; p; p = q) {
q = p->next;
FREE(p);
if (q == dlist)
break;
}
return NULL;
}
void dlist_traversal(DList dlist, void (*apply) (DList dlist, void *arg),
void *arg)
{
DList p;
assert(apply);
for (p = dlist; p; p = p->next) {
apply(p, arg);
if (p->next == dlist)
break;
}
}
双向循环链表
最新推荐文章于 2014-07-10 11:03:08 发布