[数据结构] [C语言] 线性表的链式表示和实现——循环链表、双向链表

循环链表

循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

判断空链表的条件
head == head->next;
rear == rear->next;
应用

在链表上实现将两个线性表(a1,a2,…,an)和(b1,b2,…,bm)连接成一个线性表(a1,…,an,b1,…bm)的运算。

分析:若在单链表或头指针表示的单循环表上做这种链接操作,都需要遍历第一个链表,找到结点an,然后将结点b1链到an的后面,其执行时间是O(n)。若在尾指针表示的单循环链表上实现,则只需修改指针,无须遍历,其执行时间是O(1)。

双向链表

前面提到的链式存储结构的结点中只有一个指示直接后继的指针域,因此,从某个结点出发只能顺指针往后寻查其他结点。如需查找节点的直接前驱,则需从表头指针出发。换言之,在单链表中,NextElem的执行时间为O(1),而PriorElem执行时间为O(n)。为克服这种单向性缺点,可以利用双向链表

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

存储结构
// 线性表的双向链表存储结构
typedef struct DuLNode
{
	ElemType data;
	struct DuLNode* prior;
	struct DuLNode* next;
}DuLNode, * DuLinkList;
相关算法

像ListLength,GetElem,LocateElem等仅需涉及一个方向的指针,他们的算法与线性链表的操作相同。但是在插入和删除时有很大的不同,即需要同时修改两个方向上的指针,两者算法时间复杂度均为O(n)

获取元素
DuLinkList GetElemP_DuL(DuLinkList L, int i)
{
	DuLinkList p = L->next; // 初始化,p指向第一个结点
	int j = 1; // 计数器
	while (p != L && j < i) {
		p = p->next;
		++j;
	}
	if (p == L || j > i) // 第i个元素不存在
		return NULL;
	return p;
}
插入
Status ListInsert_DuL(DuLinkList L, int i, ElemType e)
{
	// 在带头结点的双链循环线性表L中第i个位置之前插入元素e
	// i合法值1<=i<=表长+1
	
	DuLinkList p = NULL, s = NULL;
	if (!(p = GetElemP_DuL(L, i))) // 在L中确定插入位置
		return ERROR;              // p=NULL,即插入位置不合法
	if (!(s = (DuLinkList)malloc(sizeof(DuLNode))))
		return ERROR;
	s->data = e;
	s->prior = p->prior;
	p->prior->next = s;
	s->next = p;
	p->prior = s;
	return OK;
}
删除
Status ListDelete_DuL(DuLinkList L, int i, ElemType* e)
{
	// 删除带头结点的双链循环线性表L中第i个元素
	
	DuLinkList p = NULL;
	if (!(p = GetElemP_DuL(L, i))) // 在L中确定第i个元素的位置指针p
		return ERROR;              // p=NULL,即第i个元素不存在
	*e = p->data;
	p->prior->next = p->next;
	p->next->prior = p->prior;
	free(p);
	return OK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值