数据结构(C语言版)代码详解04-双循环链表

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

/***双循环链表:
是在双链表的基础上,将头节点和尾结点连接起来。
(即头节点的pre指针指向尾结点,尾结点的next指向头节点) 
***/

typedef struct Node{
	int data;
	struct Node* pre;
	struct Node* next;
}Node;

/***初始化双循环链表:(即初始头节点) 
头节点的data为0,头节点的next\pre为自己 
***/
Node* InitList(){
	Node* L=(Node*)malloc(sizeof(Node));
	L->data=0;
	L->next=L;
	L->pre=L;
	return L;
}

/***增加结点:头插法
作用:在头结点后插入一个新结点
实现:
分为两部分去思考算法
1、链表只有头结点的情况下如何增加新结点:
	头结点的next指向新结点,
	新结点的pre指向头结点,
	新结点next指向头结点(即头结点的next),
	原第一结点的pre指向新结点 
2、链表有多个结点的情况下如何增加新结点:
	头结点的next指向新结点,
	新结点的pre指向头结点,
	新结点的next指向头结点的next(即原链表第一个结点), 
	原第一结点的pre指向新结点

综上所述,可以将两者合并讨论:
	1、 新结点的pre指向头结点
	2、 新结点的next指向头结点的next 
	3、头结点指向的next指向的pre指向node 
	4、 头结点的next指向新结点
注意:必须先23再4 否则原第一结点的地址会被覆盖 
***/
void headInsert(Node* L,int data){
	Node* node=(Node*)malloc(sizeof(Node));
	node->data=data;
	node->pre=L;
	node->next=L->next;
	L->next->pre=node;
	L->next=node;
	L->data++;
}

/***增加结点:尾插法
作用:将新结点放在链表的最后一个
实现:首先要得到遍历链表,得到尾结点。
1、新结点的pre指向尾结点
2、尾结点的next指向新结点
3、新结点的next指向头结点(即尾结点原next) 
4、头结点的pre指向新结点 
***/

void tailInsert(Node* L,int data){
	Node* node=(Node*)malloc(sizeof(Node));
	node->data=data;
	L->data++;
	
	Node* p=L;
	while(p->next!=L){
		p=p->next;
	}
	
	node->pre=p;
	p->next=node;
	node->next=L;
	L->pre=node;
}
/***打印链表:
遍历链表 
***/

void printList(Node* L){
	Node* p=L->next;
	while(p!=L){
		printf("%d->",p->data);
		p=p->next;
	}
	printf("NULL\n");
} 

/***删除结点
要讨论删除尾结点和非尾结点是否有区别:
1、删除的是尾结点:
	前趋结点的next变成头结点(即尾结点的next)
	后趋结点(即头结点)的 pre变成前趋结点(即尾结点的pre)
2、删除非尾结点:
	前趋结点的next变成删除结点的next
	后趋结点的pre变成删除结点的pre
	
综上所述:
1、 前趋结点的next变成删除结点的next
2、 后趋结点的pre变成删除结点的pre
***/

int deleteList(Node* L,int data){
	Node* p=L->next;
	while(p!=L){
		if(p->data==data){
			p->pre->next=p->next;
			p->next->pre=p->pre;
			free(p);
			L->data--;
			return 1;
		}
		p=p->next;
	}
	return 0;
}


int main(){
	Node* L=InitList();  //得到头结点的地址 
	headInsert(L,5);
	headInsert(L,4);
	headInsert(L,3);
	headInsert(L,2);
	headInsert(L,1);
	tailInsert(L,6);
	tailInsert(L,7);
	tailInsert(L,8);
	tailInsert(L,9);
	tailInsert(L,10);
	
	printList(L);
	
	deleteList(L,5);
	deleteList(L,10);
	deleteList(L,1);
	
	printList(L);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值