当前位置: 首页 > news >正文

数据结构基础篇(4)

十六.循环链表

  • 概念
    • 循环链表是一种头尾相接的链表(最后一个结点的指针域指向头结点,整个链表形成一个环)
  • 优点
    • 从表任一结点出发均可找到表中其他结点
  • 判断终止
    • 由于循环链表中没有NULL指针,所以涉及遍历操作时,终止条件不像非循环链表那样判断p或p->next是否为空,而是是否等于头指针
    • 循环条件从p!=NULL到p!=L,p->next!=NULL到p->next!=L(单循环链表)
  • 时间复杂度
    • 头指针表示单循环链表
      • 找a~1的时间复杂度:O(1)
      • 找a~n的时间复杂度:O(n)
        • 注意
          • 表的操作常常在表的首尾位置上进行
    • 尾指针表示单循环链表
      • a~1的存储位置是:R->next->next
      • a~n的存储位置是:R
      • 时间复杂度均为O(1)
  • LinkList Connect(LinkList Ta,LinkList Tb)    //假设Ta.Tb都是非空的单循环链表
    {vp=Ta->next;    //p存表头结点Ta->next=Tb->next->next;    //Tb表头连接Ta表尾delete Tb->next;    //释放Tb表头结点Tb->next=p;    //修改指针return Tb;
    }  

十七.双向链表

  • 双向链表的由来
    • 查找某结点的后续结点的执行时间=O(1)
      • 单链表结点->有指示后继的指针域->后继结点
    • 查找某结点的前驱结点的执行时间=O(n)
      • - ->无指示前驱的指针域->依次寻找前驱结点
  • 双向链表的概念
    • 在单链表的每个结点里再增加一个指向其直接前驱的指针域prior,这样链表就形成了有两个方向不同的链。
  • 双向链表的特点
    • 双向链表也有循环表
      • 让头结点的前驱指针指向链表的最后一个节点
      • 让最后一个节点的后继指针指向头结点
  • 双向链表结构的对称性
    • p->prior->next=p=p->next->prior
  • 在双向链表中有些操作(如:ListLength、GetElem等),因仅涉及一个方向的指针,所以它们的算法与线性链表的相同。
  • 在插入、删除时,则需同事修改两个方向上的指针,两个的操作的时间复杂度都为O(n)。

双向链表的插入

void ListInsert_DuL(DuLinkList &L,Init i,ElemType e)    //在带头结点的双向循环链表L中第i个位置之前插入元素e
{if(!(p=GetElemP_DuL(L,i)))return ERROR;s=new DuLNOde;s->date=e;s->prior=p->prior;p->prior->next=s;s->next=p;p->prior=s;return OK;
}//ListInsert_Dul

双向链表的删除

void ListDelete_DuL(DuLinkList &L,Init i,ElemType &e)    //删除带头节点的双向循环链表L的第i个元素,并返回e
{if(!(p=GetElemP_DuL(L,i)))return ERROR;e=p->data;p->prior->next=p->next;p->next->prio=p->prior;free(p)return OK;
}//ListDelete_Dul

十八.单链表,循环链表和双向链表的时间效率比较

时间效率的比较

查找表头结点(首元结点)

查找表尾结点

查找结点*P的前驱结点

带头结点的单链表L

L->next

时间复杂度O(1)

从L->next依次向后遍历时间复杂度O(n)

通过p->next无法找到其前驱

带头结点仅设头指针L的循环单链表

L->next

时间复杂度O(1)

从L->next依次向后遍历时间复杂度O(n)

通过p->next可以找到其前驱 时间复杂度O(n)

带头结点仅设尾指针R的循环单链表

R->next|

时间复杂度O(1)

R 时间复杂度O(1)

通过p->next可以找到其前驱 时间复杂度O(n)

带头结点的双向循环链表L

L->next

时间复杂度O(1)

L->prior

时间复杂度O(1)

p->prior 时间复杂度O(1)

十九.顺序表和链表的比较

  • 链式存储结构的优点
    • 节点空间可以动态申请和释放
    • 数据元素的逻辑次序靠节点的指针来指示,插入和删除时不需要移动数据元素
  • 链式存储结构的缺点
    • 存储密度小,每个结点的指针域需额外占用存储空间。当每个节点的数据域所占字节不多时,指针域所占存储空间的比重闲得很大。
      • 存储密度
        • 概念
          • 结点数据本身所占的存储量和整个节点结构所占的存储量之比
        • 公式
          • 存储密度=结点数据本身占用的空间/结点占用的空间总量
        • 比较
          • 顺序表存储密度1,链式小于1。
    • 链式存储结构是非随机存储结构。对任一结点的操作都要从头指针依指针链查找到该结点,增加了算法的复杂度。
  • 顺序表和链表比较图

比较项目\存储结构

顺序表

链表

空间-存储空间

预先分配,导致空间闲置或溢出现象

动态分配,不会出现存储空间闲置或溢出现象

空间-存储密度

不用为表示结点间的逻辑关系而增加额外的存储开销,存储密度等于1

需要借助指针来体现元素间的逻辑关系,存储密度小于1.

时间-存取元素

随机存储,按位置访问元素的时间复杂度O(1)

顺序存储,按位置访问元素时间复杂度O(n)

时间-插入、删除

平均移动约表中一半元素,时间复杂度O(n)

不需要移动元素,确定插入,删除位置后,时间复杂度O

适用情况

  • 表长变化不大,能事先确定变化的范围。
  • 很少进行插入或删除操作,经常按元素位置序号访问数据元素。
  • 长度变化较大
  • 频繁进行插入或删除操作

二十.线性表的应用

  • 线性表的合并
    • 问题
      • 假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合A=AUB
    • 解决
void union(List &La,List Lb)
{La_len=ListLength(La);Lb_len=ListLength(Lb);for(i=1;i<=Lb_len;i++){GetElem(Lb,i,e);if(!LocateElem(La,e))ListInsert(&La,++La_len,e);    }
}    //算法的时间复杂度是:O(ListLength(La)*ListLength(Lb))
  • 有序表的合并
    • 问题
      • 已知线性表La和Lb中的数据元素按值非递减有序排列,现要求LA和Lb归并为一个新的线性表Lc,Lc中的数据元素扔按值非递减有序排列。
    • 解决
      • 创建一个空表Lc
      • 依次从La或Lb中“摘取”元素值较小的节点插入到Lc表的最后,直到其中一个表边空为止
      • 继续将La或Lb其中一个表的剩余节点插入在Lc表的最后

用顺序表来实现

void MergeList_Sq(SqList LA,SqList Lb,SqList &LC)
{pa=LA.elem;pb=LB.elem;    //指针pa和pb的初值分别指向两个表的第一个元素LC.length=LA.length+LB.length;    //新表长度为待合并量表的长度之和LC.elem=new ElemType[LC.length];    //为合并后的新表分配一个数组空间pc=LC.elem;    //指针pc指向新表的第一个元素pa_last=LA.elem+LA.length-1;    //指针pa_last指向LA表的最后一个元素pb_last=LB.elem+LB.length-1;     //指针pa_last指向LB表的最后一个元素while(pa<=pa_last && pb<=pb_last)    //两个表都非空{if(*pa<=*pb)*pc++=*pa++;    //依次“摘取”两表中的最小值else *pc++=*pb++;                                                          }while(pa<=pa_last)*pc++=*pa++;     //LB表已到达表尾,将LA中剩余元素加入LCwhile(pb<=pb_last)*pc=++=*pb++;    //LA表已到达表尾,将LB中剩余元素加入LC
}    //MergeList_Sq//算法的时间复杂度是:O(ListLength(La)*ListLength(Lb))

用链表来实现

void MergeList_L(SqList &La,SqList &Lb,SqList &Lc)
{pa=La->next;pb=Lb->next;pc=Lc=La;    //用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data<=pb->data){pc->next=pa;pc=pa;pa=pa->next;        }               else{pc->next=pb;pc=pb;pb=pb->next;        }     }pc->next=pa?pa:pb;  //插入剩余段delete Lb;    //释放Lb的头结点
}    //算法的时间复杂度是:O(ListLength(La)*ListLength(Lb))
  • 一元多项式的运算
    • 多项式创建
    • 创建一个只有头结点的空链表
    • 根据多项式的项的个数n,循环n次执行以下操作
      • 生成一个新结点*s
      • 输入多项式当前项的系数和指数赋给新节点*s的数据域
      • 设置一前驱指针pre,用于指向待找到的第一个大于输入项指数的结点的前驱,pre初值指向头结点。
      • 指针q初始化,指向首元结点
      • 循链向下逐个比较链表中当前结点与输入项指数,找到第一个大与输入项指数的节点*q
      • 将输入项结点*s插入到结点*q之前
void CreatePolyn(Polynomial &P,int n)    //输入m项的系数和指数,建立表示多项式的有序链表P
{P=new PNode;p->next=NULL;    //先建立一个带头结点的单链表for(i=1;i<=n;i++)    //依次输入n个非零项{s=new PNode;    //生成新节点cin>>s->coef>>s->expn;    //输入系数和指数pre=P;    //pre用于保存q的前驱,初值为头结点q=P->next;    //q初始化,指向首元结点while(q&&q->expn<s->expn)    //找到第一个大于输入项指数的项*q{pre=q;q=q->next;        }    s->next=q;    //将输入项s插入到q和其前驱结点pre之间pre->next=s;}
}

相关文章:

数据结构基础篇(4)

十六.循环链表 概念 循环链表是一种头尾相接的链表&#xff08;最后一个结点的指针域指向头结点&#xff0c;整个链表形成一个环&#xff09;优点 从表任一结点出发均可找到表中其他结点判断终止 由于循环链表中没有NULL指针&#xff0c;所以涉及遍历操作时&#xff0c;终止条…...

使用cad绘制一个螺旋输送机

1、第一步&#xff0c;绘制一个矩形 2、使用绘图中的样条线拟合曲线&#xff0c;绘制螺旋线。 绘制时使用上下辅助线、阵列工具绘制多个竖线保证样条线顶点在同一高度。 3、调整矩形右侧的两个顶点&#xff0c;使其变形。 矩形1和矩形2连接时&#xff0c;使用blend命令&#…...

迭代器模式(行为型)

目录 一、前言 二、迭代器模式 三、总结 一、前言 迭代器模式(Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;提供一种方法顺序访问一个聚合对象中各个元素&#xff0c;而又不暴露该对象的内部表示。总的来说就是分离了集合对象的遍历行为&#xff0c;抽象出…...

Django——Admin站点(Python)

#前言&#xff1a; 该博客为小编Django基础知识操作博客的最后一篇&#xff0c;主要讲解了关于Admin站点的一些基本操作&#xff0c;小编会继续尽力更新一些优质文章&#xff0c;同时欢迎大家点赞和收藏&#xff0c;也欢迎大家关注等待后续文章。 一、简介&#xff1a; Djan…...

React 组件通信

1.从父组件向子组件传递参数: 父组件可以通过props将数据传递给子组件。子组件通过接收props来获取这些数据。 // 父组件 const ParentComponent () > {const data Hello, Child!;return <ChildComponent childData{data} />; }; ​ // 子组件 const ChildCompone…...

【再探】设计模式—访问者模式、策略模式及状态模式

访问者模式是用于访问复杂数据结构的元素&#xff0c;对不同的元素执行不同的操作。策略模式是对于具有多种实现的算法&#xff0c;在运行过程中可动态选择使用哪种具体的实现。状态模式是用于具有不同状态的对象&#xff0c;状态之间可以转换&#xff0c;且不同状态下对象的行…...

新人硬件工程师,工作中遇到的问题list

新人硬件工程师能够通过面试&#xff0c;已经证明是能够胜任硬件工程师职责&#xff0c;当然胜任的时间会延迟&#xff0c;而不是当下&#xff0c;为什么呢&#xff1f;因为学校学习和公司做产品&#xff0c;两者之间有差异&#xff0c;会需要适应期。今天来看看新人硬件工程师…...

如何在Linux系统中搭建Zookeeper集群

一、概述 ZooKeeper是一个开源的且支持分布式部署的应用程序&#xff0c;是Google的Chubby一个开源的实现&#xff1b;它为分布式应用提供了一致性服务支持&#xff0c;包括&#xff1a;配置维护、域名服务、分布式同步、组服务等。 官网&#xff1a;https://zookeeper.apach…...

C++:vector的模拟实现

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;vector的模拟实现》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&…...

QT系列教程(5) 模态对话框消息传递

模态对话框接受和拒绝消息 我们创建一个模态对话框&#xff0c;调用exec函数后可以根据其返回值进行不同的处理&#xff0c;exec的返回值有两种&#xff0c;Qt的官方文档记录的为 QDialog::Accepted QDialog::RejectedAccepted 表示接受消息&#xff0c; Rejected表示拒绝消息…...

Linux学习笔记(清晰且清爽)

本文首次发布于个人博客 想要获得最佳的阅读体验&#xff08;无广告且清爽&#xff09;&#xff0c;请访问本篇笔记 Linux安装 关于安装这里就不过多介绍了&#xff0c;安装版本是CentOS 7&#xff0c;详情安装步骤见下述博客在VMware中安装CentOS7&#xff08;超详细的图文教…...

2.5Bump Mapping 凹凸映射

一、Bump Mapping 介绍 我们想要在屏幕上绘制物体的细节&#xff0c;从尺度上讲&#xff0c;一个物体的细节分为&#xff1a;宏观、中观、微观宏观尺度中其特征会覆盖多个像素&#xff0c;中观尺度只覆盖几个像素&#xff0c;微观尺度的特征就会小于一个像素宏观尺度是由顶点或…...

数字化前沿:Web3如何引领未来技术演进

在当今数字化时代&#xff0c;随着技术的不断发展和创新&#xff0c;Web3作为一种新兴的互联网范式&#xff0c;正逐渐成为数字化前沿的代表。Web3以其去中心化、加密安全的特性&#xff0c;正在引领着未来技术的演进&#xff0c;为全球范围内的科技创新带来了新的可能性和机遇…...

【kubernetes】探索k8s集群的存储卷、pvc和pv

目录 一、emptyDir存储卷 1.1 特点 1.2 用途 1.3部署 二、hostPath存储卷 2.1部署 2.1.1在 node01 节点上创建挂载目录 2.1.2在 node02 节点上创建挂载目录 2.1.3创建 Pod 资源 2.1.4访问测试 2.2 特点 2.3 用途 三、nfs共享存储卷 3.1特点 3.2用途 3.3部署 …...

UI线程和工作线程

引用&#xff1a;windows程序员面试指南 工作线程 只处理逻辑的线程&#xff0c;例如&#xff1a;启动一个线程&#xff0c;用来做一个复杂的计算&#xff0c;计算完成之后&#xff0c;此线程就自动退出&#xff0c;这种线程称为工作线程 UI线程 Windows应用程序一般由窗口…...

RandLA-Net 训练自定义数据集

https://arxiv.org/abs/1911.11236 搭建训练环境 git clone https://github.com/QingyongHu/RandLA-Net.git搭建 python 环境 , 这里我用的 3.9conda create -n randlanet python3.9 source activate randlanet pip install tensorflow2.15.0 -i https://pypi.tuna.tsinghua.e…...

洛谷 B3642:二叉树的遍历 ← 结构体方法 链式前向星方法

【题目来源】https://www.luogu.com.cn/problem/B3642【题目描述】 有一个 n(n≤10^6) 个结点的二叉树。给出每个结点的两个子结点编号&#xff08;均不超过 n&#xff09;&#xff0c;建立一棵二叉树&#xff08;根结点的编号为 1&#xff09;&#xff0c;如果是叶子结点&…...

飞腾+FPGA多U多串全国产工控主机

飞腾多U多串工控主机基于国产化飞腾高性能8核D2000处理器平台的国产自主可控解决方案&#xff0c;搭载国产化固件,支持UOS、银河麒麟等国产操作系统&#xff0c;满足金融系统安全运算需求&#xff0c;实现从硬件、操作系统到应用的完全国产、自主、可控&#xff0c;是国产金融信…...

uni-app实现页面通信EventChannel

uni-app实现页面通信EventChannel 之前使用了EventBus的方法实现不同页面组件之间的一个通信&#xff0c;在uni-app中&#xff0c;我们也可以使用uni-app API —— uni.navigateTo来实现页面间的通信。注&#xff1a;2.8.9 支持页面间事件通信通道。 1. 向被打开页面传送数据…...

等保系列之——网络安全等级保护测评工作流程及工作内容

#等保测评##网络安全# 一、网络安全等级保护测评过程概述 网络安全等级保护测评工作过程包括四个基本测评活动&#xff1a;测评准备活动、方案编制活动、现场测评活动、报告编制活动。而测评相关方之间的沟通与洽谈应贯穿整个测评过程。每一项活动有一定的工作任务。如下表。…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...