循环链表

06 循环链表

拥有回忆 提交于 2020-01-22 00:27:54
以下笔记来自王老师的视频截图: https://www.bilibili.com/read/cv3285768 目录 循环链表 两个链表的合并 双向链表1 双向链表结构的对称性 双向链表的插入 双向链表的删除 单链表、循环链表、双向链表的比较 顺序表和链表的比较 链式存储结构的优缺点 存储密度 线性表的合并 有序表的合并-用顺序表实现 有序表的合并-用链表实现 案例分析与实现 多项式运算 稀疏多项式运算 图书信息管理 循环链表 循环链表使用更多的通常是带尾指针的。 两个链表的合并 双向链表1 双向链表结构的对称性 双向链表的插入 双向链表的删除 删除操作O(1) 但是如果需要查找删除的位置 ,即if语句后面。那么就是O(n) 。 总的也是O(n)。 单链表、循环链表、双向链表的比较 顺序表和链表的比较 链式存储结构的优缺点 存储密度 线性表的合并 有序表的合并-用顺序表实现 有序表的合并-用链表实现 时间复杂度: 因为表a,表b都需要访问一遍。 空间复杂度:O(1) 因为只需在原来的链表上修改指针就行。 案例分析与实现 多项式运算 稀疏多项式运算 图书信息管理 来源: CSDN 作者: H A I 链接: https://blog.csdn.net/weixin_44199723/article/details/104060428

双向循环链表

微笑、不失礼 提交于 2020-01-21 14:25:28
文章目录 双向循环链表 双向循环链表节点结构 双向循环链表的操作 双向循环链表的末尾插入 双向循环链表的有序插入 双向循环链表节点删除 根据```element```进行删除 根据节点指针删除 双向循环链表的清空 演示与测试视频 源代码 双向循环链表   在单向循环链表中,如果要在末尾插入一个节点,必须从 head 一个节点一个节点往后查询,尽管新建节点是插入在末尾节点和起始节点之间。在节点数较多的情况下,这一过程是费时的。此外,在实际应用中,有时需要逆向访问表中元素,这对单向链表或单向循环链表结构来说显然是困难的。为解决这一问题,可将链表设计成双向链表或双向循环链表。   以带表头节点的双向循环链表为例: 双向循环链表节点结构   可见,双向循环链表的每个节点包含三个域: element 、 prev 、 next 。其中 element 域为元素域, prev 为指向前驱节点的指针, next 为指向后继节点的指针。   双向循环链表的每个节点的结构都具有如下定义的结构类型( element 域定义为 int 型数据): struct _node { int element; struct _node* prev; struct _node* next; }; typedef struct _node node; 双向循环链表的操作  

大话数据结构系列之循环链表(五)

不想你离开。 提交于 2020-01-20 01:14:47
文章目录 定义 代码实现(Java ) 定义 循环链表(circular linked list)是将单链表中终端节点的指针端由空指针改为指向头结点,就使整个单链表形成一个环。 实际含义: 存在循环的情景,例如录音机的循环播放,网易云的单曲循环功能(需要从 头 ——> 尾 ) 代码实现(Java ) Java 语言 package com.example; /* * 初始化时,含有头尾节点的单链表循环结构 * 对比单向链表优势,寻找头尾节点的时间复杂度为O[1] * 在合并双向链表时,时间复杂度为O[1] 见 unionList方法 */ public class LoopLinkList<T> { //是否可以泛型中嵌套泛型? 遗留 @SuppressWarnings("hiding") class Node<T> { protected Node<T> next; protected T data; public Node(T data){ this.data = data; } } /* 产生头结点 */ public Node<T> head; /* 产生尾结点 */ public Node<T> rear; /*线性表长度 */ private int size; /* 初始化顺序线性表 头节点,只存储指针,末节点存值,顾算一个单位*/ void initList(){

浅谈python实现链表

妖精的绣舞 提交于 2020-01-20 00:10:04
一、前言 本节主要讲解内容如下: 1、单向链表 1.1 单链表概念 1.2 用单链表实现栈 1.3 用单链表实现队列 2、循环链表 2.1 循环链表的概念 2.2 用循环链表实现队列 3、双向链表 3.1 双向链表的概念 3.2 用双向链表实现双端队列 4.、位置列表的抽象数据类型 4.1 概念 在前面的博客中,我们了解到python的list类是一个经过高度优化的基于数组的结构,但是它有一些明显的缺点: 1.一个动态数组的长度可能超过实际存储数组元素所需的长度。 2.在实时系统中对操作系统的摊销边界是不可接受的。 3.在一个数组内部执行插入和删除操作的代价太高。 这里我们介绍一个链表的数据结构,链表和数组不同,链表依赖于更多的分布式表示方法,采用称为节点的轻量级对象,分配给每一个对象。每个节点维护一个指向它的元素的引用,并含一个或者多个指向相邻节点的引用,这样做的目的是为了集中的表示序列的线性顺序。 二、单向链表的概念 困,明天再更。 参考书籍:《数据结构与算法》 来源: CSDN 作者: 半符合适应 链接: https://blog.csdn.net/qq_36186768/article/details/104045338

[数据结构]-04顺序表和链表

妖精的绣舞 提交于 2020-01-13 08:51:22
顺序表 按照顺序存储方式存储的线性表称为顺序表。 什么是有序顺序表? 若顺序表中的元素按其值有序,则称其为有序顺序表。 顺序表的插入 设顺序表 A A A 的长度为 n n n ,将字段值为 i t e m item i t e m 的元素插入到第 i i i 个位置,插入步骤如下: 保证顺序表存储空间未满,并且插入位置合法 将第 i i i 个位置元素及其之后的所有元素后移一个位置 插入成功后,线性表长度变为 n + 1 n+1 n + 1 顺序表的删除 设顺序表 A A A 的长度为 n n n ,删除第 i i i 个位置的元素,删除步骤如下: 保证删除位置合服性 将第 i i i 个位置之后的所有元素前移一个位置 删除成功后,线性表长度变为 n − 1 n-1 n − 1 顺序表总结 特点:存储地址连续,数据元素存储依次存放;数据元素类型相同,数据元素可随机存取 优点:存储空间的利用率高,存取速度快,适用于存取需求多的线性表 缺点:静态存储形式,数据元素的个数不能自由扩充 (受存储空间的限制);在插入、删除某个元素时,需要移动大量元素 单链表 结点只有一个指针域的链表成为单链表。 数据域 d a t a data d a t a 存放该结点的数据域的值,指针域 n e x t next n e x t 存放该结点的后继结点的地址信息。 什么是空链表? 若表中只有头结点

线性表之链式存储结构

冷暖自知 提交于 2020-01-10 02:58:05
线性表的顺序存储结构要求逻辑关系上相邻的元素在物理位置上也相邻,这样方便了随机存取,但是在插入和删除元素时,需要移动大量元素,而线性表的链式存储则不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构的可随机存取的优点,不过在插入和删除元素时比较方便。 单链表 单链表可由头指针唯一确定,在C语言中可用“结构指针”来描述 : 1: typedef struct Node { 2: ElemType data; 3: struct Node *next; 4: }Node, *LinkList; 有时,我们会在单链表的第一个结点之前附设一个结点,称之为头结点。头结点的数据域可以不存储任何信息,也可以存储如链表的长度等一些附加信息。头结点的指针域指向第一个结点,如果线性表为空,则头结点的指针域为NULL。 循环链表 表中最后一个结点的指针域指向第一个结点,整个链表形成一个环。 循环链表的操作与单链表基本一致,差别在于算法中的循环条件不是p或者p->next是否为空, 而是他们是否等于头指针。 有时候,在循环链表中设立尾指针而不设头指针,可以使某些操作简化。 双向链表 在双向链表的结点中有两个指针域, 其一指向直接后继,另一指向直接前驱,在C语言中可描述如下: 1: typedef struct Node { 2: ElemType data; 3: struct Node

java循环链表

你说的曾经没有我的故事 提交于 2020-01-09 02:13:21
package com.zrp.link; /** * 节点类 * @author zrp * */ class Node{ public Node(){} public int data; //结点数据 public Node next; //指向下一结点的指针 Node(int data){ this.data = data; } /** * 获取节点数据 * @param null * @return int */ public int getNodeData(){ return this.data; } } /** * 报数链表类 * @author zrp * */ public class NumberOffLink { public Node headNode; //头结点 private int size; //链表长度 public int getSize() { return size; } public void setSize(int size) { this.size = size; } /** * 构造函数,无参构造函数 * @param n,node */ public NumberOffLink(){ } /** * 有参构造函数,创建链表 * @param 人数account */ public NumberOffLink(int

数据结构~链表

南楼画角 提交于 2020-01-08 05:41:05
返回目录 概况 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,链表比较方便插入和删除操作。 链表 (Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表:顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。链表通常由一连串节点组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向明上一个/或下一个节点的位置的链接("links")。链表最明显的好处就是

单链表及循环链表已知问题整理

ε祈祈猫儿з 提交于 2019-12-31 22:05:58
1. 如何快速查找到一个单链表的中间位置 方法:通过快慢指针来查找中间位置。设置两个指针,快指针和慢指针,慢指针每次移动一次,快指针每次移动两次。当快指针出现null,则到达链表末尾。此时慢指针的数据就是中间值。 2. 一个单链表,输出此链表的倒数第k各节点。 方法一:遍历单链表,求出链表长度N。(求出K点的位置P)N-K=P,再次从头开始遍历至P点。 方法二: 1.定义两个指针p1,p2分别指向链表的头部。 2.P1前进值K点,则p1,p2相距K点。 3.p1,p2开始同时前进,每次前进一个节点。 4.当p1到达末尾,p2所在的位置就是K点的位置。 3. 怎么判断链表是否是循环链表 方法一:通过快慢指针来检测链表是否是循环链表。设置两个指针,快指针和慢指针,慢指针每次移动一次,快指针每次移动两次,如果快指针追赶上慢指针,则为循环链表,否则不是循环链表。 方法二:借助hasmap判断是否经历过此点。 4. 求有环单链表的环长 在环上相遇后,记录第一次相遇点为Pos,之后指针slow继续每次走1步,fast每次走2步。在下次相遇的时候fast比slow正好又多走了一圈,也就是多走的距离等于环长。   设从第一次相遇到第二次相遇,设slow走了len步,则fast走了2 len步,相遇时多走了一圈:     环长=2 len-len。 5.求有环单链表的环连接点位置

数据结构——双向循环链表

佐手、 提交于 2019-12-28 17:15:56
一、双向循环链表 二、用C语言实现双向循环链表 1、构造存储结构 typedef int datatype ; typedef struct doublelist { datatype data ; struct doublelist * next , * prev ; } double_list , * double_plist ; 2、初始化 初始化主要工作:①申请头结点内存空间;② head->next = head; head->prev = head; 3、插入结点 (1)、向p指向的结点后面插入new指向的结点 步骤①: new->next = p->next; 步骤②: p->next->prev = new; 步骤③: new->prev =p; 步骤④: p->next = new; /* 向p指向的结点后面插入new指向的结点 */ void insert_doublelist_behind ( double_plist p , double_plist new ) { new -> next = p -> next ; p -> next -> prev = new ; new -> prev = p ; p -> next = new ; } (2)、向p指向的结点前面插入new指向的结点 步骤①: new->prev = p->prev; 步骤②: p-