双向循环链表

/*
 * 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;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值