大话数据结构,双端循环链表,源程序

在网上找了下大话数据结构这本书的源码,发现第三章虽然有说到双端链表却没给出实现,于是自己在线性链表的基础上修改了一下,源码如下:

我将只有一个头结点的时候,头结点的next和prior都指向自己。

主要是注意一下插入的时候基本都遵循这个模型:,也就是找到要插入的地方的前一个数据的坐标(可能是头结点)。

#include "stdio.h"    
#include "string.h"
#include "ctype.h"      
#include "stdlib.h"   
#include "io.h"  
#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /* 存储空间初始分配量 */
#define RANDOMINT(m,n) ((int)(rand()%(n-m+1)+m))


typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */


Status visit(ElemType c)
{
	printf("%d ", c);
	return OK;
}


typedef struct DulNode
{
	ElemType data;
	struct DulNode *next;
	struct DulNode *prior;
}DulNode;
typedef struct DulNode *DuLinkList;


/* 初始化顺序线性表 */
Status InitList(DuLinkList *L)
{
	if ((*L = (DuLinkList)malloc(sizeof(DulNode))) != NULL)
	{
		(*L)->next = (*L);
		(*L)->prior = (*L);
		return OK;
	}
	else return ERROR;
}

/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Status ListEmpty(DuLinkList L)
{
	if (L->next != L)
		return FALSE;
	else
		return TRUE;
}

/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
Status ClearList(DuLinkList *L)
{
	DuLinkList p, q;
	q = (*L)->next;
	(*L)->next = *L;
	(*L)->prior = *L;
	while (q != *L) //首先判断首元素是否空
	{
		p = q->next;
		free(q);
		q = p;
	}
	return OK;
}

/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(DuLinkList L)
{
	int i = 0;
	DuLinkList p = L->next; /* p指向第一个结点 */
	while (p != L)
	{
		p = p->next;
		++i;
	}
	return i;
}

/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值 */
Status GetElem(DuLinkList L, int i, ElemType *e)
{
	if (i > ListLength(L) || i < 1 || ListLength(L) == 0)
		return ERROR;
	int j = 1;
	DuLinkList p;
	p = L->next;

	while (p!=L && j < i)
	{
		p = p->next;
		++j;
	}
	*e = p->data;
	return OK;
}

/* 初始条件:顺序线性表L已存在 */
/* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int LocateElem(DuLinkList L, ElemType e)
{

	int i = 1;
	DuLinkList p = L->next;
	while (p!=L && p->data != e)
	{
		p = p->next;
		++i;
		if (i > ListLength(L))
		{
			return 0;
		}
	}
	return i;
}

/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(DuLinkList *L, int i, ElemType e)
{
	if (i < 1)
	{
		return ERROR;
	}
	int j = 0;
	DuLinkList p, q, s;
	p = (*L);
	while (j < i - 1) //这里判断到达表末了不能写在while循环里面了
	{
		p = p->next;
		j++;
		if (p == *L) break;
	}
	if (j < i - 1)
	{
		return ERROR;
	}
	s = (DuLinkList)malloc(sizeof(DulNode));
	s->data = e;
	q = p->next;
	p->next = s;
	q->prior = s;
	s->prior = p;
	s->next = q;

	return OK;
}

/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(DuLinkList L)
{
	if (ListLength(L) < 1)
		return ERROR;
	DuLinkList p = L->next;
	while (p != L)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
	return OK;
}

/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(DuLinkList *L, int i, ElemType *e)
{
	if (i >= 1 && i <= ListLength(*L))
	{
		DuLinkList p = (*L), q;
		int j = 0;
		while (j < i - 1) //找到第i-1个元素
		{
			p = p->next;
			++j;
		}

		q = p->next;
		*e = q->data;
		p->next = q->next;
		q->next->prior = p;
		free(q);
		return OK;
	}
	else return ERROR;
}


///*  随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
void CreateListHead(DuLinkList *L, int n)
{
	DuLinkList p, q, s;
	int i = 0;
	srand(time(0));                         /* 初始化随机数种子 */
	InitList(L);
	p = *L;

	for (i = 0; i != n; ++i)
	{
		s = (DuLinkList)malloc(sizeof(DulNode));
		s->data = i;
		q = p->next;
		p->next = s;
		q->prior = s;
		s->prior = p;
		s->next = q;
	}
}


/*  随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
void CreateListTail(DuLinkList *L, int n)
{
	DuLinkList p, q;
	int i = 0;
	srand(time(0));                         /* 初始化随机数种子 */
	InitList(L);
	p = *L;
	while (i < n)
	{
		i++;
		ListInsert(L, i, i);
	}
}

int main()
{
	DuLinkList L;
	ElemType e;
	Status i;
	int j, k;
	i = InitList(&L);
	printf("初始化L后:ListLength(L)=%d\n", ListLength(L));
	for (j = 1; j <= 5; j++)
		i = ListInsert(&L, 1, j);
	printf("在L的表头依次插入1~5后:L.data=");
	ListTraverse(L);

	printf("ListLength(L)=%d \n", ListLength(L));
	i = ListEmpty(L);
	printf("L是否空:i=%d(1:是 0:否)\n", i);

	i = ClearList(&L);
	printf("清空L后:ListLength(L)=%d\n", ListLength(L));
	i = ListEmpty(L);
	printf("L是否空:i=%d(1:是 0:否)\n", i);

	for (j = 1; j <= 10; j++)
		ListInsert(&L, j, j);
	printf("在L的表尾依次插入1~10后:L.data=");
	ListTraverse(L);

	printf("ListLength(L)=%d \n", ListLength(L));

	ListInsert(&L, 1, 0);
	printf("在L的表头插入0后:L.data=");
	ListTraverse(L);
	printf("ListLength(L)=%d \n", ListLength(L));

	GetElem(L, 5, &e);
	printf("第5个元素的值为:%d\n", e);

	for (j = 3; j <= 4; j++)
	{
		k = LocateElem(L, j);
		if (k)
			printf("第%d个元素的值为%d\n", k, j);
		else
			printf("没有值为%d的元素\n", j);
	}


	k = ListLength(L); /* k为表长 */
	for (j = k + 1; j >= k; j--)
	{
		i = ListDelete(&L, j, &e); /* 删除第j个数据 */
		if (i == ERROR)
			printf("删除第%d个数据失败\n", j);
		else
			printf("删除第%d个的元素值为:%d\n", j, e);
	}
	printf("依次输出L的元素:");
	ListTraverse(L);

	j = 5;
	ListDelete(&L, j, &e); /* 删除第5个数据 */
	printf("删除第%d个的元素值为:%d\n", j, e);

	printf("依次输出L的元素:");
	ListTraverse(L);

	i = ClearList(&L);
	printf("\n清空L后:ListLength(L)=%d\n", ListLength(L));
	CreateListHead(&L, 20);
	printf("整体创建L的元素(头插法):");
	ListTraverse(L);

	i = ClearList(&L);
	printf("\n删除L后:ListLength(L)=%d\n", ListLength(L));
	CreateListTail(&L, 20);
	printf("整体创建L的元素(尾插法):");
	ListTraverse(L);

	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值