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


title: 数据结构-循环链表与双向链表
date: 2022-10-16 12:18:05
tags:数据结构

循环链表

特点

表中最后一个节点的指针域指向头节点,整个链表形成一个环

如图


操作

循环单链表的操作和单链表基本一致(点这里查看单链表操作),差别在于:当链表遍历时,判别当前指针p是否指向表节点的终止条件不同。在单链表中,判别条件为p!=NULL或p->next = NULL,而循环单链表的判别条件为p! = NULL或p->next !=L。

在某些情况下,在循环链表中设立尾指针而不设立头指针,可使一些操作简化。如将两个线性表合并成一个表时。

将上图两表合并

主要语段:

p = B->next->next; 建立工作指针p,存放表2的头节点的后继指针地址(表2的红色节点)

B->next = A->next; 将表2尾节点的指针指向表1的头节点(表3的绿色线)

A->next = p; 将表1的尾指针A指向表2头节点的后继节点(表3蓝色的线)

最后free表2的头节点;


双向链表

特点

在单链表中,查找直接后继的执行时间为O(1),而查找直接后前驱的执行时间为O(n)。为克服单链表这中单向性的缺点,可利用双向链表。

如图

算法描述

//双向链表的存储结构
typedef struct DuLNode
{
	ElemType data;	//数据域
    struct DuLNode *prior;	//指向直接前驱
    struct DuLNode *next;	//指向直接后驱
}DuLNode, *DuLinkList;

在双向链表中,有些操作(ListLength,GetElem和LocateElem等)仅需涉及一个方向的指针,他们的算法描述和线性链表一样(点这里查看单链表操作)。但在插入,删除时有很大不同。


操作

插入

算法描述

Status ListInsert_Dul(DuLinkList &L, int i, ElemType e)
{//在带头节点的双向链表L中第i个元素之前插入元素e
	if(!(p = GetElem_DuL(L, i)))	//在L中确定第i个元素的位置指针p
    {
		return ERROR;	//p为NULL时,第i个元素不存在
    }
    s = new DuLNode;	 //生成新节点*s
    s->data = e;	//将节点*s的数据域置为e
    s->prior = p->next;	//将节点*s插入L中,此步对应下图①
    p->prior->next = s;	//对应下图②
    s->next = p;	//对应下图③
    p->prior = s;	//对应下图④
    
    return OK;
}

如图


删除

算法描述

Stauts ListDelete_Dul(DuLinkList &L, int i)
{//删除头节点的双向链表L中的第i个元素
	if(!(p = GetElem_DuL(L, i)))	//在L中确定第i个元素的位置指针p
    {
		return ERROR;	//p为NULL时,第i个元素不存在
	}
    p->prior->next = p->next;	//修改被删除节点的前驱节点的后继指针,对应下图①
    
    p->next->prior = p->prior;	//修改被删除节点的后继节点的后继指针,对应下图②
    
    delete p;	//释放被删除节点的空间
    return OK;
}

如图


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值