第一章#1.3循环和双向链表

###循环链表###

 

循环链表是一种头尾相接的链表(即:表中最后一个结点的指针域指向头结点,整一个链表形成一个环)。

注意:循环链表无NULL指针,故涉及遍历操作时,其终止条件就不像非循环链表那样判断p或p->next是否为空,而是判断它们是否等于头指针。

循环条件:p!=L或者p->next!=L 

由于尾指针满足r->next->next就是指向首元结点,作用相当于头指针。因此在实际使用过程中,更经常使用的是这种尾指针的循环链表,这样既可以从头遍历,也可以从尾部遍历,有利于降低时间复杂度。

例子:如下图

操作如下图:

  • p存表头结点

  • Tb表头接到Ta表尾

  • 释放Tb表头结点

  • 修改指针

算法:

LinkList Connecto(LinkList Ta, LinkList Tb) {
	//假设Ta、Tb都是非空的单循环链表
    p = Ta -> next;		//p存表头结点
    Ta->next = Tb->next->next; 		//Tb表头连接Ta表尾
    delete Tb->next;	//释放Tb表头结点,或使用free(Tb->next);
    return Tb;
}	//O(1)



###双向链表###

双向链表相较于单链表和单循环链表需要重新定义结点类型

(prior,data,next)前指针域,数据域,后指针域

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

 

双向链表的一些操作实现

  •  算法1:双向链表的插入操作

        

void ListInsert DuL(DuLinkList &L, int i, ElemType e) {
    //在带头结点的双向循环链表L中第i个位置之前插入元素e 
if(!(p=GetElemP_DuL(L, i))) return ERROR;//获得第i个位置,与单链表操作同,不赘述
s=new duLNode; s->date= e 
s->prior =p->prior; p->prior->next s; 
s->next=p; p->prior=s;
return OK 
} // ListInsert DuL 
  • 算法2:双线链表的删除操作

        

void ListDelete DuL(DuLink &L, int i, ElemType &e) {
   //删除带头结点的双向循珠链表L的第ⅰ个元素,并用e返回 
if(!(p=GetElemP DuL(L, i)) return ERROR; //找到位置不合理返回错误
	e=p->data;	//用于保存删除的数据,以便需要
   	p->prior->next=p->next;
	p->next->prior=p->prior; 
   	delete p;	//free(p)
	return OK;
}//LinkDelete_DuL
//查找算法时间复杂度是O(n),在这里最复杂,故算法时间复杂度也是O(n)




###单链表、循环链表、双向链表时间效率比较###

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值