线性表的链式存储结构——双向循环链表

双向循环链表和单链表一样,是由一个个的节点组成,只是前者拥有两个指针域,一个指向前一个节点的地址另一个指向后一个节点。

双向链表的储存结构
typedef int data_t;
typedef struct node{
	data_t data;
	struct node *prior,*next;
}dlinklist;
创建一个双向循环链表

首先需要创建一个头结点并初始化

dlinklist *CreateDlinklist(){
	dlinklist * head = (dlinklist *)malloc(sizeof(dlinklist));
	if(head == NULL)
		return NULL;
	head->data = -1;
	head->prior = head->next = head;
	return head;
}
计算双向循环链表的有效长度

有效长度是不包含头结点的,要实现这个我们就需要定义一个指针p来对链表进行遍历。

int GetLengthDlinklist(dlinklist *head){
	if(head == NULL)
		return -1;
	dlinklist *p = head->next;
	int len = 0;
	while(p != head){
		//p = p->next;
		len++;
		p = p->next;
	}
	return len;
}
判断是否为空

当头节点的直接前驱指向本身是就是为空的

int Dlinklist_is_empty(dlinklist *head){
	if(head == NULL)
		return -1;
	return head->prior == head;
}
插入数据

按位置进行数据的插入,这里我们需要创建一个新的节点来存放需要插入的数据,在定义一个新的指针对链表进行遍历找出需要插入的位置,然后将数据插入指定的位置。如图:
在这里插入图片描述实现代码:

int InsertDlinklist(dlinklist *head,int pos,data_t data){
	if(head == NULL)
		return -1;
	if(pos < 0 || pos > GetLengthDlinklist(head))
		return -1;
	dlinklist *p = (dlinklist *)malloc(sizeof(dlinklist));
	if(p == NULL)
		return -1;
	dlinklist *p = (dlinklist *)malloc(sizeof(dlinklist));   //创建一个节点来存需要插入的数据
	p->data = data;
	p->next = p->prior = NULL;
	dlinklist *q = head;    //定义一个节点指针来对链表进行遍历
	while(pos--){
		q = q->next;
	}
	p->next = q->next;
	p->prior = q;
	q->next->prior = p;
	q->next = q;
	return 0;
}
按位置删除数据

首先需要遍历找到需要删除的节点,所以就需要定义一个指针进行遍历,在此之前还需要对该位置进行判断是否符合要求。找到位置后将该节点删除,并释放节点。如图:
在这里插入图片描述实现代码

int DeDlinklistBypos(dlinklist *head,int pos){
	if(head == NULL)
		return -1;
	if(pos < 0 || pos >  GetLengthDlinklist(head) || Dlinklist_is_empty(head))
		return -1;
	dlinklist *p = head;
	while(pos--){
		p = p->next;
	}
	p->next->prior = p->prior;
	p->prior->next = p->next;
	free(p);
	p = NULL;
	return 0;
}
按值进行数据的删除

遍历找到要删除的值,然后将值所在的节点删除并释放(操作和按位置删除类似)

int DeDlinklistBydata(dlinklist *head,data_t data){
	if(head == NULL)
		return -1;
	dlinklist *p = head->next;
	while(p != head){
		if(p->data == data)
			break;
		else
			p = p->next;
	}
	p->next->prior = p->prior;
	p->prior->next = p->next;
	free(p);
	p = NULL;
	return 0;
}
按位置进行数据修改

找到需要修改的位置节点直接进行数据修改

int ChangeDlinklistBypos(dlinklist *head,int pos,data_t data){  
	if(head == NULL)
		return 0;
	if(pos<0 || pos> Get_dlinklist_length(head) || Dlinklist_is_empty(head))
		return -1;
	dlinklist *p = head;
	while(pos--){
		p = p->next;
	}
	p->data = data;
	return 0;
}
按值进行数据修改

遍历找到需要修改的值所在的节点,然后进行数据修改,将新的值赋给旧的值

int ChangeDlinklistBydata(dlinklist *head,data_t old,data_t new){  
	if(head == NULL)
		return -1;
	dlinklist *p = head->next;
	while(p){
		if(p->data == old)
			break;
		else
			p = p->next;
	}
	p->data = new;
	return 0;
按位置进行查找,返回值

找出位置节点,将其中的值返回

int SearchDlinklistBypos(dlinklist *head,int pos){  
	if(head == NULL)
		return -1;
	if(pos<0 || pos >Get_dlinklist_length(head) || Dlinklist_is_empty(head))
		return -1;
	dlinklist *p = head;
	while(pos--){
		p = p->next;
	}
	return p->data;
}
按值进行查找,返地址

找到值所在的节点,将节点的地址返回

dlinklist *SearchDlinklistBydata(dlinklist *head,data_t data){
	if(head == NULL)
		return NULL;
	dlinklist *p = head->next;
	while(p != head){
		if(p->data == data)
			break;
		else
			p = p->next;
	}
	return p;
}
遍历双循环链表

定义一个指针对链表进行遍历,并输出每个节点的值

void printfDlinklist(dlinklist *head){  
	if(head == NULL)
		return ;
	dlinklist *p = head->next;
	while(p != head){
		printf("%3d",p->data);
		p = p->next;
	}
	printf("\n");
	return ;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值