• 数据结构之循环链表


    循环链表和单链表的区别:

    1:单链表的表尾节点的next指针指向NULL,而循环链表的表尾节点指针next指向头结点
    在这里插入图片描述

    2:单链表从一个节点出发只能找到后续的各个节点,而循环链表从一个节点出发可以找到其他任意一个节点
     3:时间复杂度不同
    在这里插入图片描述

    定义循环单链表:

    带头结点:

    方法:和普通单链表的定义方法相同

    typedef struct Linklist
    {
    	Elemtype data;
    	struct LNode* next;
    }LNode,Linklist*;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    循环链表的初始化:

    方法:和普通单链表的初始化方法基本相同,不同之处在于循环链表的头结点next指向头结点

    bool INitlist(Linklist& L)
    {
    	L = (Node*)malloc(sizeof(LNode));
    	if (L == NULL)
    		return false;
    	L->next = L;
    	return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    循环链表的判空操作:

    方法:和普通单链表的判空方法基本相同,不同之处在于循环链表的判空是判断头结点的指针是否指向头结点,而普通单链表的判空是判断头结点的指针是否指向NULL

    bool Empty(Linklist& L)
    {
    	if (L->next = L)
    		return true;
    	else
    		return false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    判断节点p是否为循环单链表的表尾节点:

    方法:和普通单链表的判断方法基本相同,不同之处在于循环链表的判空是判断p节点的指针是否指向头结点,而普通单链表的判空是判断p节点的指针是否指向NULL

    bool istail(Linklist& L)
    {
    	if (p->next == L)
    		return true;
    	else
    		return false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    双链表和循环双链表的区别:

    1:普通双链表表头节点的prior指向NULL,表尾节点的next指向NULL,而循环双链表表头节点的prior指向表尾节点,表尾节点的next指向头结点
    在这里插入图片描述

    定义循环双链表:

    带头结点:

    方法:和定义普通双链表的方法相同

    typedef struct DNode
    {
    	ElemType data;
    	struct DNode* prior, * next;
    }LNode,Linklist*;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    循环双链表的初始化:

    方法:和普通双链表的初始化基本相同,不同点在于循环双链表的两个节点指针指向的都是表头,而普通双链表两个节点指针指向的是NULL

    bool InitList(Linklist& L)
    {
    	L = (DNode*)malloc(sizeof(DNode));
    	if (L == NULL)
    		return false;
    	L->prior=L:
    	L->next = L;
    	return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    循环链表的判空操作:

    方法:和普通双链表的初始化基本相同,不同点在于循环双链表的表尾节点指针指向的是表头,而普通双链表的表尾节点指针指向的是NULL

    bool Empty(Linklist& L)
    {
    	if (L->next == L)
    		return true;
    	else
    		return false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    判断节点p是否为循环单链表的表尾节点:

    方法:和普通双链表的判断方法基本相同,不同之处在于循环链表的判空是判断p节点的指针是否指向头结点,而普通双链表的判空是判断p节点的指针是否指向NULL

    bool istail(Linklist& L)
    {
    	if (p->next == L)
    		return true;
    	else
    		return false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    双链表的插入:

    在此之前,我们学习过普通双链表的插入操作,有一个特殊情况是当插入的元素是最后一个元素时,我们无法找到它的前驱结点,也就是说p->next->prior = s不成立,由此我们进行了判断操作:判断插入的节点是否为表尾节点。

    bool InitList(DNode*p,DNode*s)
    {
    	s->next = p->next;
    	p->next->prior = s;
    	s->prior = p; p->next = s;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    但在循环双链表的插入操作中,插入的元素是否为表尾元素并不是我们所担心的问题,因为表尾元素它是指向头结点的,由此我们是能够找到该节点的前驱指针。

    双链表的删除:

    在之前我们学到过普通双链表的删除操作,当要删除的元素为最后一个节点时,我们没办法找到它的前驱节点,也就是q->next->prior = p无法实现。

    bool DelteNextDNode(DNode* p)
    {
    	if (p == NULL)
    		return false;
    		DNode*q=p->next;
    	if (q == NULL)
    		return false;
    	p->next = q->next;
    	if (q->next != NULL)
    		q->next->prior = p;
    	free(q);
    	return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    但在循环双链表的删除操作中,删除的元素是否为表尾元素并不是我们所担心的问题,因为表尾元素它是指向头结点的,由此我们是能够找到该节点的前驱指针。

  • 相关阅读:
    2023年【四川省安全员A证】复审考试及四川省安全员A证考试试题
    docker
    深度解读智能化编码的技术架构与实践案例
    独有且优质,这些Mac软件绝了
    UDP 报文结构与注意事项全解析
    JSP CMS 校园服务系统myeclipse定制开发mysql数据库网页模式java编程jdbc
    GO语言gin框架实战-04-websocket链接
    ubuntu18.04下zookeeper安装与简单使用
    岩藻多糖-聚已内酯 Fucoidan-PCL 聚已内酯-PEG-岩藻多糖
    一个”.java”源文件中是否可以包括多个类?有什么限制?(企业真题)
  • 原文地址:https://blog.csdn.net/m0_64365419/article/details/126358232