【数据结构】循环链表和双向链表介绍

介绍了单链表,提到了单链表的一些限制,基于单链表,本文介绍循环链表和双向链表,可以解决一些对于单链表来说比较复杂的问题,对单链表不熟的可以去看上一篇文章

循环链表

尾结点的指针域指向头结点

使用头指针不方便,多使用尾指针

带尾指针的循环链表的合并

在这里插入图片描述

  • 存表头结点

  • Tb表头连接到Ta表尾

  • 释放Tb表头空间

  • 修改指针

❓疑惑:第一步先将Tb的next域指向Ta的头结点不可以吗?这样可以省去存头结点的步骤

算法描述

LinkList Connect(LinkList Ta,LinkList Tb){
    p=Ta->next;
    Ta->next=Tb->next->next;
    delete Tb->next;
    Tb->next=p;
}

时间复杂度:O(1)

双向链表

双向链表有两个指针域

双向链表的结构定义

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

双向循环链表

  • 头结点的前驱指针指向尾结点
  • 尾结点的后继指针指向头结点
  • 空表的前驱指针和后继指针都指向自身

在这里插入图片描述

双向链表结构具有对称性,p->next->prior=p->prior->next

基本操作算法

获取表长、取值、查找算法和单链表的相同

插入

在这里插入图片描述

共需要操作四个指针:

  • s的前驱
  • p的前驱的后继(即a的后继,但是没有a的指针)
  • s的后继
  • p的前驱

p的前驱在最后修改,防止找不到p的前驱

算法描述

void ListInsert_DuL(DuLLinkList &L;int i,Elemype e){
    if(!(p=GetElemP_DuL(L,i)))  //用已有方法将p指向第i个位置,若该位置不合法,返回error
        return ERROR;
    //创建新结点
    s=new DuLNOde;
    s->data=e;
    //插入新结点
    s->prior=p->prior;
	p->prior->next=s;
	s->next=p;
    p->prior=s;
    
    return OK;
}//ListInsert_DuL

时间复杂度😮(n)

删除

在这里插入图片描述

删除p结点,共需操作两个指针:

  • p的前驱的后继
  • p的后继的前驱

算法描述

void ListDelete_DuL(DuLink &L,int i,ElemType &e){	//删除带头结点的双向循环链表L的第i个元素,并用e返回
    if(!(p=GetElemtP_DuL(L,i)))
        return ERROR;
    e=p->data;
    //删除
    p->prior->next=p->next;
	p->next->prior=p->prior;
    delete p;
    return OK;
}//ListDelete_DuL

时间复杂度😮(n)

时间效率对比

查找表头结点(首元结点)查找表尾结点查找结点*p的前驱结点
带头结点的单链表L->next
O(1)
从L->next向后遍历
O(n)
通过p->next找不到前驱结点
带头结点仅设头指针的循环单链表L->next
O(1)
从L->next向后遍历
O(n)
能找到前驱结点
O(n)
带头结点仅设尾指针的循环单链表R->next
O(1)
R
O(1)
能找到前驱结点
O(n)
带头结点的双向循环链表L->next
O(1)
L->prior
O(1)
p->prior
O(1)

顺序表和链表的比较

链式存储结构的优点

  • 结点空间可以动态申请和释放
  • 数据元素的逻辑次序靠结点的指针来指示,插入和删除时不需要移动数据元素

链式存储结构的缺点

  • 存储密度小,每个结点的指针域需额外占用存储空间。当每个结点的数据域所占字节不多时,指针域所占存储空间的比重显得很大

存储密度 = 结点数据本身占用的空间 结点占用的空间总量 存储密度=\frac{结点数据本身占用的空间}{结点占用的空间总量} 存储密度=结点占用的空间总量结点数据本身占用的空间

​ 一般的,存储密度越大,存储空间的利用率就越高。顺序表的存储密度为1,链表的存储密度小于1

  • 链式存储结构是非随机存取结构。对任意结点的操作都要从头指针依次查找该结点,增加了算法的复杂度

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值