数据结构与算法(四)链式存储结构(其他链表)

本文介绍了循环链表和双向循环链表的特点及操作。循环链表允许从任意节点开始查找,检查空链表通过判断尾指针是否指向头指针。插入和删除操作的时间复杂度为O(n)。双向循环链表则增加了前驱指针,方便查找前驱节点,但插入和删除操作需修改两个指针,时间复杂度同样为O(n)。文章还讨论了不同链表操作的时间复杂度,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、循环链表

        优点:可以从任意一个结点出发查找其他结点

         检空:判断尾指针是否指向头指针

p!=L
p->next!=L

         通过头指针 H 查找an的时间复杂度为O(n)、a1的时间复杂度为O(1)

                 a1的存储位置为R->next->next

                 an的存储位置为R

                通过尾指针 R 查找an、a1的时间复杂度为O(1)

        将两个带尾指针的循环链表合并

LinkList Connect(LinkList Ta,LinkList Tb){
    p=Ta->next;//p保存表头结点
    Ta->next = Tb = next->next;//Tb表头连接Ta表尾
    delete Tb->next;//释放Tb的头指针
    Tb->next = p;//修改指针
    return Tb;
}

时间复杂度为O(1)

二、双向循环链表(在每个结点里增加一个前驱指针域prior)

        可以直接查找一个结点的前驱结点(不需要像单链表一样绕场一周)

        定义

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

         双向链表具有对称性,在插入和删除时需要修改两个指针,操作的时间复杂度均为O(n)

         插入

void ListInsert_Dul(DuLinkList &L,int i, ElemType e){
    if(!(p=GetElemP_Dul(L,i))) return ERROR;//查找位置,如果没有直接返回错误
    s= new DuLNode;    s->data=e;
    
    s->prior = p->piror;    p->prior->next=s;//连接前驱元素
    s->next = p;     p->piror=s;//连接后继元素
    return OK;
}

        删除

void ListDelete_Dul(DuLink &L,int i,ElemType &e){
    if(!(p=GetElemP_Dul(L,i))) return ERROR;//查找位置,如果没有直接返回错误
    e=p->data;
    
    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、付费专栏及课程。

余额充值