C语言数据结构之双向循环链表

双向循环链表的结构

由于单链表只能单向访问,在插入删除时有时需要寻找尾结点比较麻烦,在此基础上设置了双向循环链表,头尾互相指定。

typedef int DlistDataType;
typedef struct DListNode
{
	int data;
	struct DListNode* next;
	struct DListNode* prev;
}SDListNode;

接口函数

(此处展示的是带哨兵位的链表,在main函数中,SDListNode*plist=NULL;,plist仅仅只是用来存放头结点的地址,往后的一切操作都是在这个头结点之后去进行插入删除,并不会改变plist所存储的值,自然不用传&plist,直接plist即可。)

//链表内容初始化
SDListNode* SDListInit();
//尾插
void SDListNodePushBack(SDListNode* head, DlistDataType x);
//打印
void SDListNodePrint(SDListNode* head);
//尾删
void SDListNodePopBack(SDListNode* head);
//头插
void SDListNodePushFront(SDListNode* head, DlistDataType x);
//头删
void SDListNodePopFront(SDListNode* head);
//寻找某一个元素
SDListNode* SDListFind(SDListNode* head,int pos);
//指定位置插入
void SDListNodeInsert(SDListNode* pos, DlistDataType x);
//指定位置删除
void SDListNodeEarse(SDListNode* pos);
//开辟空间的销毁
void SDListNodeDestroy(SDListNode* head);

接口函数的实现

//创建头结点
SDListNode* SDListInit()
{
	SDListNode* head = (SDListNode*)malloc(sizeof(SDListNode));
	head->next = head;
	head->prev = head;
	return head;
}
SDListNode* BuySDListNode(DlistDataType x)
{
	SDListNode* newnode = (SDListNode*)malloc(sizeof(SDListNode));
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}
void SDListNodePushBack(SDListNode* head, DlistDataType x)
{
	assert(head);
	SDListNode* newnode = BuySDListNode(x);
	SDListNode* tail = head->prev;
	tail->next = newnode;
	newnode->prev = tail;
	head->prev = newnode;
	newnode->next = head;
}
void SDListNodePrint(SDListNode* head)
{
	SDListNode* print = head->next;
	while (print != head)
	{
		printf("%d ", print->data);
		print = print->next;
	}
	printf("\n");
}
void SDListNodePopBack(SDListNode* head)
{
	assert(head);
	assert(head->next !=head);
	SDListNode* tail = head->prev;
	SDListNode* prev = tail->prev;
	prev->next = head;
	head->prev = prev;
	free(tail);
}
//此处头插,是指在哨兵位后的第一个节点出插入,而不是在哨兵位处插入
void SDListNodePushFront(SDListNode* head, DlistDataType x)
{
	SDListNode* newnode = BuySDListNode(x);
	SDListNode* next = head->next;
	head->next = newnode;
	newnode->prev = head;
	newnode->next = next;
	next->prev = newnode;
}
void SDListNodePopFront(SDListNode* head)
{
	assert(head);
	assert(head->next != head);
	SDListNode* cur = head->next;
	SDListNode* next = cur->next;
	head->next = next;
	next->prev = head;
	free(cur);
}
SDListNode* SDListFind(SDListNode* head, int pos)
{
	SDListNode* cur = head->next;
	while (cur != head)
	{
		if (cur->data == pos)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
//在指定位置之前插入
void SDListNodeInsert(SDListNode* pos, DlistDataType x)
{
	SDListNode* newnode = BuySDListNode(x);
	SDListNode* prev = pos->prev;
	prev->next = newnode;
	newnode->prev = prev;
	newnode->next = pos;
	pos->prev = newnode;
}
void SDListNodeEarse(SDListNode* pos)
{
	SDListNode* posPrev = pos->prev;
	SDListNode* posNext = pos->next;
	posPrev->next = posNext;
	posNext->prev = posPrev;
	free(pos);
}
//最后在text.c中调用这个函数后,还应写:head=NULL;才算把这个链表销毁
void SDListNodeDestroy(SDListNode* head)
{
	SDListNode* cur = head->next;
	while (cur != head)
	{
		SDListNode* next = cur->next;
		free(cur);
		cur = next;
	}
}

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值