线性表——双向循环链表的C语言实现

在双向链表的结点中有两个指针域,一个指向直接后继, 另一个指向直接前驱。

双向循环链表的C语言实现

头文件

#include<stdio.h>
#include<stdlib.h>

//结果函数状态代码 
#define TRUE	1
#define FALSE	0
#define OK		1
#define ERROR		0
#define INFEASIBLE	-1
#define OVERFLOW	-2
#define MAXSIZE 100		//顺序表可能达到的最大长度 

typedef int Status;// Status--函数的类型,其值是函数结果的状态代码
typedef char ElemType; 
typedef struct DuLNode	//声明节点类型和指向节点的指针类型 
{
	ElemType	data;		//节点的数据域 
	struct DuLNode *next, *prior; 	//节点的指针域 
}DuLnode, *DuLinkList;			//LinkList为指向结构体Lnode的指针类型

双向循环链表的初始化

Status InitList(DuLinkList L)		//双向循环的初始化
{
	L = (DuLinkList)malloc(sizeof(DuLnode));
	L->next = L;
	L->prior = L;
	return OK;
}

判断双向循环链表是否为空

int ListEmpty(DuLinkList L)		
{
	if(L->next == L) return 1;	//空表返回1
	else return 0;				//非空返回0 
}

销毁双向循环链表

Status DestroyList(DuLinkList L)	//销毁双向循环链表
{
	DuLnode *p, *q = L;
	while(p!=L)
	{
		p = q;
		q = q->next;
		printf("%c,",p->data);
		free(p);
	}
	printf("销毁成功!!!\n");
	return OK;
} 

清空双向循环链表

Status ClearList(DuLinkList L)		//清空双向循环链表
{
	DuLnode *p, *q = L->next;
	while(p!=L)
	{
		p = q;
		q = q->next;
		printf("%c,",p->data);
		free(p);
	}
	L->next = L;
	L->prior = L;
	printf("清空成功!!!\n");
	return OK;	
}

求双向循环链表表长

int GetLength(DuLinkList L)			//求双向循环链表表长
{
	DuLnode *p = L->next;
	int i=0;
	while(p!=L)
	{
		i++;
		p = p->next;
	}
	return i;
}

输出显示双向循环链表,1为正向输出,0为反向输出

void ShowList(DuLinkList L, int status)		
{
	DuLnode *p; 
	if(status) 
	{
		p = L->next;
		while(p!=L)
		{
			printf("%c,", p->data);
			p = p->next;
		}
	}
	else 
	{
		p = L->prior;
		while(p!=L)
		{
			printf("%c,", p->data);
			p = p->prior;
		}
	}
	printf("\n");
}

获取双向循环链表第 i 个位置的元素,放入e中

Status GetElem(DuLinkList L, int i, ElemType *e)
{
	DuLnode *p = L->next;
	int j = 1;
	while(p!=L && j<i)
	{
		p = p->next;
		j++;
	}
	
	if(p==L && j>i) return FALSE;
	*e = p->data;
	return OK;
}

按值查找,返回地址或位置, num存放位置, p存放地址

Status LocateElem(DuLinkList L, ElemType e, int *num, DuLnode *p)
{
	p = L->next;
	int i = 1;
	while(p!=L && p->data!=e)		
	{
		p = p->next;
		i++;
	}
	if(p!=L)
	{
		*num = i;
		return OK;
	}
	else return FALSE;
}

在第i个节点前插入值为e的新节点

Status ListInsert(DuLinkList L, int i, ElemType e)
{
	DuLnode *p = L->next;
	int j = 1;
	while(p!=L && j<i-1)				//找到第 i-1个节点 
	{
		p = p->next;
		j++; 
	}
	if(p==L && j>i-1) return ERROR;
	DuLnode *s = (DuLinkList)malloc(sizeof(DuLnode));
	s->data = e;
	s->next = p->next;
	p->next->next->prior = s;
	p->next = s;
	s->prior = p;
	return OK;
}

删除第i个节点,利用e保存删除结点数据

Status ListDelete(DuLinkList L, int i, ElemType *e)
{
	DuLnode *q, *p = L->next;
	int j = 1;
	while(p!=L && j<i-1)				//找到第 i-1个节点 
	{
		p = p->next;
		j++;
	}
	if(p==L && j>i-1) return ERROR;
	q = p->next;
	p->next = q->next;
	q->next->next->prior = p;
	*e = q->data;
	free(q);
	printf("删除成功, %c\n", *e);
	return OK;
}

双向循环链表的创建----头插法

DuLinkList CreatList_Head(int n)		//双向循环链表的创建----头插法
{
	DuLinkList L = (DuLinkList)malloc(sizeof(DuLnode));
	DuLnode *p, *q;
	L->next = L;
	L->prior = L;
	q = L;					//q指向第一个节点 
	char i;
	int j = 0;
	for(i='h';j<n;i--,j++)
	{
		p = (DuLinkList)malloc(sizeof(DuLnode));
		p->data = i;
		L->next = p;
		p->next = q;
		p->prior = L;
		q->prior = p;
		q = p;
	}
	return L;
}

双向循环链表的创建----尾插法

DuLinkList CreatList_Tail(int n)		//双向循环链表的创建----尾插法
{
	DuLinkList L = (DuLinkList)malloc(sizeof(DuLnode));
	DuLnode *p, *q;
	L->next = L;
	L->prior = L;
	q = L;					//q指向尾结点 
	char i;
	int j = 0;
	for(i='a';j<n;i++,j++)
	{
		p = (DuLinkList)malloc(sizeof(DuLnode));
		p->data = i;
		p->next = L;
		p->prior = q;
		q->next = p;
		L->prior = p;
		q = p;
	}
	return L;
}

主函数

int main()
{
	Status InitList(DuLinkList L);	//双向循环的初始化
	int ListEmpty(DuLinkList L);		//判断链表是否为空
	Status DestroyList(DuLinkList L);	//销毁双向循环链表
	Status ClearList(DuLinkList L);	//清空双向循环链表
	int GetLength(DuLinkList L);		//求双向循环链表表长
	Status GetElem(DuLinkList L, int i, ElemType *e);		//获取双向循环链表第 i 个位置的元素,放入e中 
	Status LocateElem(DuLinkList L, ElemType e, int *num, DuLnode *p);	//按值查找,返回地址或位置, num存放位置, p存放地址
	Status ListInsert(DuLinkList L, int i, ElemType e); 	//在第i个节点前插入值为e的新节点
	Status ListDelete(DuLinkList L, int i, ElemType *e);	//删除第i个节点,利用e保存删除结点数据 
	void ShowList(DuLinkList L, int status);			//输出显示双向循环链表,1为 正向输出,0为反向输出 
	DuLinkList CreatList_Head(int n);		//双向循环链表的创建----头插法
	DuLinkList CreatList_Tail(int n);		//双向循环链表的创建----尾插法
	
	DuLinkList L;
	L = CreatList_Head(8);		//头插法创建链表
//	L = CreatList_Tail(8);		//尾插法创建链表 
	if(!ListEmpty(L))			//判断链表是否为空
	{
		printf("非空\n");		
	}
	else	printf("空\n"); 
	ShowList(L, 1);				//正向输出链表 
	ShowList(L, 0);				//反向输出链表 
	printf("链表表长为:%d\n", GetLength(L));
	printf("表尾元素为:%c\n",L->prior->data);
	printf("表头元素为:%c\n",L->next->data);
	
	int i = 5, loc;
	DuLnode p;
	ElemType e1, e = 'c', e2;
	GetElem(L, i, &e1);
	printf("第%d个节点的值为:%c\n", i, e1);
	LocateElem(L, e, &loc, &p);
	printf("%c所在节点的位置为:%d,地址为%d\n", e, loc, &p);
	
	ListDelete(L, i, &e2);
	ShowList(L, 1);
	ListInsert(L, i, e2);
	ShowList(L, 1);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值