数据结构——双链表


一、什么是双链表

概念:在使用一个单链表时,我们可以通过next指针很轻松地访问下一个结点,但是如果想要找到一个结点的前驱结点却没有什么好的办法,只能从头开始遍历。既然我们想要很轻松地访问前驱结点,那么定义一个像next一样的指针指向前驱结点不就好了吗!确实如此,这样每个结点都有两个指针域,分别指向前驱结点和后继结点,这样的链表就是双链表。
代码

typedef struct DNode
{
	ElemType data;
	struct DNode *prior, *next;	//前驱结点指针,后继结点指针
}DNode, *DLinkList;

在这里插入图片描述

二、双链表的操作

1.初始化

①带头结点

bool InitDLinkList(DLinkList &L)
{
	L = new DNode;	//创建一个头结点并分配空间
	if (L == NULL)
		return false;	//内存不足分配失败
	L->prior = NULL;	//头结点的prior指针永远指向NULL
	L->next = NULL;		//头结点后面暂时还没有结点
	return true;
}

②不带头结点

bool InitDLinkList(DLinkList &L)
{
	L = NULL;
	return true;
}

2.判空

bool Empty(DLinkList L)
{
	if (L->next ==NULL)
		return true;
	else
		return false;
}

3.插入

bool InsertNextDNode(DNode* p, DNode* s)
{//在给定p结点后插入一个结点s
	if (p == NULL || s == NULL)
		return false;	//传入的结点有错误
	s->next = p->next;	//新结点的后继结点指向p结点的后继结点
	if (p->next != NULL)	//如果p结点不是最后一个结点
		P->next->prior = s;	//p的后继结点的前驱指针指向新结点
	s->prior = p;	//新结点的前驱指针指向前驱结点p
	p->next = s;	//p结点的后继指针指向新结点,这一步要放在最后写
	return true;
}

上述代码是一个结点的后插操作,得益于双链表有两个指针,所以其他的插入操作比如前插操作,按位序插入等都可以在后插的基础上很轻松地完成。

4.删除

bool DeleteNextDNode(DNode* p)
{//删除结点p的后继结点
	if (p == NULL)
		return false;	//传入的结点有误
	DNode* q = p->next;		//令q指向p的后继结点
	if (q == NULL)
		return false;	//p没有后继结点
	p->next = q->next;	//把要删除的结点的下一个结点接在p结点后面
	if (q->next != NULL)	//如果要删除的结点不是最后一个结点
		q->next->prior = p;	
	delete q;	//释放被删除结点中的数据
	return true;
}

其他删除操作例如按位序删除,也可以借助上述代码完成。

5.销毁

bool DestoryList(DLinkList &L)
{//循环释放各个数据结点
	while (L->next != NULL)
		DeleteNextDNode(L);
	delete L;
	L->NULL;
	return true;
}

双链表的其他操作与单链表类似,代码不再重复给出,双链表在往前找这一方面还是比较方便的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值