数据结构 链表之循环链表与双向链表

循环链表

循环链表的特点是表中最后一个节点的指针域指向第一个结点,整个链表成为一个由链指针相链接的环。通常在表中第一个结点之前加上一个头结点,并令头指针指向最后一个结点。一般情况下头结点的数据域不存储任何信息。空表的循环链表由只含一个自成循环的头结点表示。

循环链表的操作与单链表基本一致,差别仅在于算法中判别表尾的循环条件不是(顺链扫描的)指针p是否为NULL,而是它是否等于头指针

      非空的循环链表 头指针a指向最后一个结点 

 空的循环链表

循环链表两表的合并

对于单链表的话,需要用指针P遍历去找到表尾,执行时间为O(n)。而循环链表仅需将一个表的表尾和另一个表的表首相接即可,执行时间为O(1)。

双向链表

以上链表中只能顺着表往后查询其他结点,若要查询前驱结点则需要从表头开始遍历。 求前驱的执行时间为O(n),这种缺点可由双向链表克服。双向链表的结点中有两个指针域,一个指向直接后继,一个指向直接前驱。 

如下为双向链表的存储结构:

typedef struct DuLNode {
	char data;
	struct DuLNode *prior;
	struct DuLNode *next;
}DuLNode,*DuLinkList;

 准确的说应该是双向循环链表

双向链表的插入和删除

对于双向链表的插入,每次插入一个结点都要改变四个指针,分别是目标结点的前驱指针目标结点的前驱结点的后继指针新结点的前驱指针新结点的后继指针

void ListInsert_DuL(DuLinkList &L, DuLNode *p, DuLNode *s)
{
	//在p所指的结点前插入s所指的新结点           插入
	s->prior = p->prior;   //将新结点的前驱指针指向目标结点的前驱结点
	p->prior->next = s;   //将目标结点的前驱结点的后继指针指向新结点
	s->next = p;         //将新结点的后继指针指向目标结点
	p->prior = s;       //将目标结点的前驱指针指向新结点
}

对于双向链表的删除,只需要调整目标结点的前驱结点的后继指针目标结点的后继结点的前驱指针即可。同时将要删除的结点的数据值赋给e;

void ListDelete_DuL(DuLinkList &L, DuLNode *p, int e)
{
	//删除双向循环链表L中 指针p所指向的结点 并用e返回其数据值            删除
	e = p->data;                   //用e去接收待删除结点的数据值
	p->prior->next = p->next;      //将目标结点的前驱结点的后继指针指向目标结点的后继结点
	p->next->prior = p->prior;     //将目标结点的后继结点的前驱指针指向目标结点的前驱结点
	delete p;            //删除目标结点
}

本笔记所依据的教材为严薇敏版的《数据结构及应用算法教程》

所引用的图片来源于华中师范大学云课堂

所有代码在Visual Studio 2017上均可正常运行

如有错误欢迎指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值