线性表——循环链表和双向链表

本文介绍了链表的两种特殊形式:循环链表和双向链表。循环链表的最后一个节点指针指向头节点,允许从任一节点开始循环遍历。双向链表每个节点包含前驱和后继指针,支持双向遍历。文中详细展示了使用头插法和尾插法创建双向链表的C语言实现过程。
摘要由CSDN通过智能技术生成

目录

1.1 循环链表

1.2 双向链表

双链表的建立

头插法

尾插法

总结


1.1 循环链表

循环链表是链式存储结构的另一种形式。

特点:表中的最后一个结点的指针域指向头结点,整个链表形成一个环。因此,从表中的任意一个结点出发均可以找到表中的其他结点。与普通的线性链表的操作基本一致,差别在于循环条件不是p或p->next 是否为空,而是它们是否等于头指针。


1.2 双向链表

由于以上讨论的线性链表结构都是只有一个直接指向后继结点的指针域,所以遍历的方式都是只能从某一个结点向后遍历,为了克服这一个缺点,可以使用双向链表

特点:双向链表的结点有两个指针域,一个指向直接后继结点,一个指向直接前驱结点

typedef struct DuLNode{
    ElemType data;
    struct DuLNode *prior;
    struct DuLNode *next;

}DuLNode,*DuLinkList;

双链表的建立

头插法

void CreatListF(DLinkNode *&L,ElemType a[], int n){
    DLinkNode *s;
    L=(DLinkNode *)malloc(sizeof(DLinkNode));
    L->prior=L->next=NULL;
    for(int i=0;i<n;i++){
        s=(DLinkNode *)malloc(sizeof(DLinkNode));
        s->data=a[i];
        s->next=L->next;
        if(L->next!=NULL){
            L->next->prior=s;
        }
        L->next=s;
        s->prior=L;
    }
}

函数接受三个参数:指向双向链表的指针L(通过引用传递),一个存储元素的数组a[],以及元素的数量n

在函数内部,首先通过malloc函数为链表头节点L分配内存空间,并将其前驱指针prior和后继指针next都设置为NULL,表示链表为空。

然后,通过循环遍历数组a[],依次创建链表节点并将元素赋值给节点的data成员。对于每个新创建的节点s,将它的next指针指向原链表头节点的下一个节点,并更新原链表头节点的后继指针指向s。如果原链表头节点的下一个节点不为空,则将其前驱指针指向s。最后,将s的前驱指针指向原链表头节点,完成节点的插入操作。


尾插法

void CreateListR(DLinkNode*& L, ElemType a[], int n) {
    DLinkNode* s;
    L = (DLinkNode*)malloc(sizeof(DLinkNode));
    L->prior = L->next = NULL;
    DLinkNode* tail = L; // 尾指针,初始指向头节点
    
    for (int i = 0; i < n; i++) {
        s = (DLinkNode*)malloc(sizeof(DLinkNode));
        s->data = a[i];
        s->next = NULL;
        s->prior = tail;
        tail->next = s;
        tail = s; // 更新尾指针为当前节点
    }
}

它也接受三个参数:指向双向链表的指针L(通过引用传递),存储元素的数组a[]以及元素的数量n

在函数内部,首先通过malloc函数为链表头节点L分配内存空间,并将其前驱指针prior和后继指针next都设置为NULL,表示链表为空。然后,声明一个尾指针tail,初始时指向头节点。

接下来,通过循环遍历数组a[],依次创建链表节点并将元素赋值给节点的data成员。对于每个新创建的节点s,将其next指针设置为NULL,将其prior指针指向当前尾节点tail,然后将当前尾节点的next指针指向s,实现节点的插入。最后,更新尾指针tail为当前节点s,以便下一次循环时将新节点插入到链表尾部。


总结

双向链表(Doubly Linked List)

  • 双向链表是一种链表数据结构,每个节点除了包含指向下一个节点的指针(next指针)外,还包含指向前一个节点的指针(prev指针)。
  • 双向链表可以双向遍历,可以从头节点向后遍历,也可以从尾节点向前遍历,这使得双向链表的某些操作更高效,例如在任意位置插入和删除节点。
  • 双向链表占用更多的内存空间,因为每个节点需要存储额外的指针。

循环链表(Circular Linked List)

  • 循环链表是一种链表数据结构,在单向链表或双向链表的基础上,将尾节点的next指针指向头节点,形成一个闭环。
  • 循环链表可以通过遍历到尾节点后,再次返回到头节点,从而实现循环遍历,可以方便地处理循环相关的问题。
  • 循环链表适用于需要循环访问数据的场景,比如实现循环队列和循环缓冲区等。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值