数据结构之线性表3

我们的目标:

1、了解线性结构的特点 掌握顺序表的定义、查找、插入和删除。

2、掌握链表的定义、创建、查找、插入和删除。

3、能够从时间和空间复杂度的角度比较两种存储结构的不同特点及其适用场合。(持续更新)


前言

本章节内容主要介绍线性表的链式表示和实现,即链表的使用。


继续上一篇内容:http://t.csdn.cn/KwKsg

三、链表

我们都知道,线性表的链式存储结构的特点是在逻辑上相邻的数据元素在物理上不一定相邻。

上一篇我们讲到了单链表,所以接下来来介绍循环链表。

1.1  循环链表

循环链表是另一种形式的链式存储结构。和单链表不同的是,它最后不是NULL,而是L(通俗来讲因为循环没有尽头)。

类似地,还有非空单循环链表和空表。如图所示:

12d9dda3e7774160925bf0a44342b813.png

5399b0cbb5a14278ac3f7f01f24c8c96.png

这说明了从循环链表中的任何一个结点的位置都可以找到其他所有结点,而单链表做不到; 

并且循环链表中没有明显的尾端——>如何避免死循环?

我们知道循环条件是

//单链表
p!=NULL
p->next!=NULL
//循环链表
p!=L
p->next!=L

进而说明对循环链表,有时不给出头指针,而给出尾指针可以更方便的找到第一个和最后一个结点。

e73e3ca9981b479b86e0bca28c104560.png

那么如何查找开始结点和终端结点?

答:开始结点:rear->next->next                  

        终端结点:rear 


1.1.2  循环链表的合并——单循环链表

下面是一个单循环链表:

978ebe97d5b241d296354a0d4af49c83.png

 代码实现:

LinkList  Connect(LinkList  Ta,LinkList  Tb)
{//假设Ta、Tb都是非空的单循环链表
          p=Ta->next;                                   //①p存表头结点
          Ta->next =Tb->next->next;                     //②Tb表头连结Ta表尾
          deleteTb->next;                               //③释放Tb表头结点
          Tb->next=p;                                   //④修改指针
          return  Tb;
}

总结:上述操作的时间复杂度为O(1)。


1.2 双向链表

如图所示:

62b2986e2ab04c97931124076d6eb7ad.png

28597552022b4c7c98e1d50a6ea4b268.png

 代码实现:

//---双向链表的存储结构---
typedef struct DuLNode{
    ElemType   data;              //数据域
    struct DuLNode  *prior;       //指向直接前驱
    struct DuLNode  *next;        //指向直接后继
}DuLNode, *DuLinkList;

双向链表分为两种,如图所示,图b中有两个环,而图a中只有一个表头结点的空表。

3b3586eec8b4427b81a16fe5818f4ca4.png

5ddbabdb197942c6b886920ac36bd13e.png

在双向链表中,若d为指向表中某一节点的指针:

 d->next->prior = d->prior->next = d


1.2.1 双向链表的插入

8e4e37d79a4e4b0eafe56068865029e6.png

代码实现: 

Status 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->prior;  
   p->prior->next=s;
   s->next=p;  
   p->prior=s;
   return OK;
}

1.2.2 双向链表的删除

d41bc25472ac4ab8a3ade4f09d0bfb49.png

1. p->prior->next=p->next;                2. p->next->prior=p->prior; 

代码实现:

Status ListDelete_DuL(DuLinkList &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;
}

四、顺序表和链表的比较

在实际应用中,我们不能说哪种的存储结构更好,由于它们各有优缺点,选用哪种存储结构,则应根据具体问题具体分析,通常从空间性能和时间性能两个方面作比较分析。

f527cd13f43e447abd87be4a333ae1d6.png

五、线性表的应用

5.1 线性表的合并 

求解一般集合的并集问题:

问题:假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合:                                  A=A    B。例如, La=(7, 5, 3, 11)      Lb=(2, 6, 3)      设合并后La=(7, 5, 3, 11, 2, 6)

步骤:

依次取出Lb 中的每个元素,执行以下操作:

1.在La中查找该元素;

2.如果找不到,则将其插入La的最后。

代码实现:

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);                     
  }
}

时间复杂度为:

7d496a02a53c456cb3c0e01d4fd66761.png

5.2 有序表的合并

有序表:线性表中的数据元素相互之间可以比较,且数据元素在线性表中依值非递减或非递增有序排列。

求解有序集合的并集问题:

问题:已知线性表La 和Lb中的数据元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列。例如,

La=(1 ,7, 8) Lb=(2, 4, 6, 8, 10, 11)   则Lc=(1, 2, 4, 6, 7 , 8, 8, 10, 11)

步骤:

1. 创建一个空表Lc;

2. 依次从 La 或 Lb 中“摘取”元素值较小的结点插入到 Lc 表的最后,直至其中一个表变空为止;

3. 继续将 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; 	//指针pb_last指向LB表的最后一个元素 
     while(pa<=pa_last && pb<=pb_last){  	//两个表都非空 
      if(*pa<=*pb) *pc++=*pa++;        	//依次“摘取”两表中值较小的结点      
      else *pc++=*pb++;      } pa++;             //LB表已到达表尾
     while(pb<=pb_last)  *pc+
     while(pa<=pa_last)  *pc++=*+=*pb++;          //LA表已到达表尾 
}//MergeList_Sq 

时间复杂度/空间复杂度为:

4c0cc2a499fa4124b9495c077f864043.png

有序表合并的优点:不需要开辟新的存储空间,可以使空间复杂度达到最低。


总结

以上就是本节所讲的内容,主要讲解链表的应用以及与顺序表的比较。希望各位大佬多多指点,我会在数据结构上一直持续更新下去!感谢佬们点支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/9248.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【中级软件设计师】—操作系统考点总结篇(二)

【中级软件设计师】—操作系统考点总结篇&#xff08;二&#xff09; 1.操作系统概述 1.1操作系统的功能 1.2 特殊的操作系统 1.3 进程的概念和状态 进程与程序的区别&#xff1a; 进程是程序的一次执行过程&#xff0c;没有程序就没有进程 程序是一个静态的概念&#xff0c;…

蓝桥杯嵌入式第十二届初赛题目解析

把蓝桥杯嵌入式第十二届的题目写完了&#xff0c;拿出来和大家一起分享。 目录 客观题 程序设计题 题目解析&#xff1a; CubeMX配置 代码演示 客观题 收集的一些历年的比赛客观题和解析&#xff0c;以及程序设计题的PDF&#xff0c;在这里分享给大家。 链接&#xff…

SHELL函数可课后作业

一、题目 1、编写函数&#xff0c;实现打印绿色OK和红色FAILED 判断是否有参数&#xff0c;存在为Ok&#xff0c;不存在为FAILED 2、编写函数&#xff0c;实现判断是否无位置参数&#xff0c;如无参数&#xff0c;提示错误 3、编写函数实现两个数字做为参数&#xff0c;返回最…

使用Schrödinger Python API系列教程 -- 介绍 (一)

使用Schrdinger Python API系列教程 – 介绍 (一) 本文档可从Schrdinger网站www.schrodinger.com/pythonapi访问。 从Python文档字符串生成的完整API文档可以在这里访问 介绍 在最高级别上&#xff0c;Schrdinger Python API提供了一个基本的分子结构类&#xff0c;并允许与…

6.S081——虚拟内存部分——xv6源码完全解析系列(2)

0.Briefly Spaeking 点此回看本系列博客的上一篇 上一篇博客中&#xff0c;我们详细分析了xv6内核代码中有关虚拟内存的部分&#xff0c;主要剖析了vm.c这个文件中的三个全局变量和6个函数&#xff0c;这篇博客紧跟着上篇博客的步伐。接着剖析和阅读接下来的源码&#xff0c;同…

用于语义分割模型的t-SNE可视化

前言 在之前的博客t-SNE可视化-Python实现中&#xff0c;对t-SNE的原理进行了一个简单的介绍&#xff0c;也给出了一个简单的使用案例。这篇博客在之前的基础上实现在语义分割模型上的t-SNE可视化。 语义分割模型中使用t-SNE的目的是&#xff0c;从模型的特征层面进行一定的可…

ftp传输文件大小有限制吗 ftp文件传输工具有哪些

这两年&#xff0c;线上办公逐渐常态化&#xff0c;相信大家对ftp这个概念也比较熟悉了。ftp&#xff0c;即文件传输协议&#xff0c;线上办公就是用ftp软件进行文件传输的。那ftp传输文件大小有限制吗,ftp文件传输工具有哪些我们一起来看看。 一、ftp传输文件大小有限制吗 f…

vue3中tsx语法一些了解

首先直接创建tsx文件 引入函数 import { defineComponent, ref } from vue 直接使用组件函数的写法 export default defineComponent({//context内有参数emit,slot,arrts,expose //解构写法setup( props,{emit,slot,arrts,expose}){}setup( props,context) {//定义函数和响应…

Vue+nodejs快递收发寄件揽件代取网点查询系统

本系统名为“基于vue快递代取系统”&#xff0c;系统主要适用于毕业设计&#xff0c;不能作为商用。系统主要分为二个大模块&#xff0c;分别为“前台”&#xff0c;“后台”。其中“前台”模块中主要包含快递公司、代取信息、公告栏、快递资讯、投诉栏等。主要提供于用户与快递…

编译技术-优化理论

一、构造控制流图&#xff08;CFG&#xff09; 关于优化&#xff0c;真的是一个令人生畏的事情&#xff0c;大致来说&#xff0c;一个优化分为两个部分&#xff1a; 分析改写 但是在课程中大多只交第一个部分&#xff0c;而不讲第二个部分&#xff0c;这就导致一种“无意义性”…

【剧前爆米花--爪哇岛寻宝】java文件操作和io流

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaEE初阶》 文章分布&#xff1a;这是一篇关于文件操作的文件&#xff0c;介绍了文件读写以及相关对象的内容&#xff0c;希望对你有所帮助&#xff01; 目录 文件操作 文件路径 绝对路径 相对路径 File类 File类的构造方…

应急响应真的很重要!

本文参考&#xff1a;2014年电信网和互联网安全操作系统基线 目录 看一下win10的用户​编辑 用户自身 查看用户命令 提权命令 看一下管理员 打开本地安全策略 将密码必须符合复杂性要求进行开启​编辑 参照基线效果 ​编辑 效果图&#xff1a; 开启日志​编辑 用even…

SpringSession深入浅出(一)

一、session来由 要谈session&#xff0c;一定是要说到用它带场景http协议。http协议是无状态协议&#xff0c;就像鱼的记忆&#xff0c;即使是同一浏览器给客户端给同一个服务器再来请求&#xff0c;已经记不起来你是谁。在互联网早期&#xff0c;承载网页大部分都是静态简单…

Chapter2 : SpringBoot配置

尚硅谷SpringBoot顶尖教程 1. 全局配置文件 SpringBoot使用一个全局的配置文件 application.properties 或者 application.yml &#xff0c;该配置文件放在src/main/resources目录或者类路径/config目录下面&#xff0c; 可以用来修改SpringBoot自动配置的默认值。 yml是YA…

【Lin-CMS内容管理系统框架 v0.3.6】内置用户管理/权限管理/日志系统等常见功能

【Lin-CMS内容管理系统框架 v0.3.6】内置用户管理/权限管理/日志系统等常见功能 Lin-CMS 是林间有风团队经过大量项目实践所提炼出的一套内容管理系统框架。 Lin-CMS 可以有效的帮助开发者提高 CMS 的开发效率。 Lin CMS 特点&#xff1a; Lin CMS 的构筑思想是有其自身特点的。…

【JS】1651- 10 个 JS 中 try...catch 使用技巧

作为一位 Web 前端工程师&#xff0c;JavaScript 中的 try...catch 是我们常用的特性之一。本文我将分享 10 个有用的 try...catch 使用技巧&#xff0c;让你在处理异常时更加得心应手。1. 捕获所有异常如果你想捕获代码中所有可能的异常&#xff0c;可以使用一个不带参数的 ca…

Leetcode.100 相同的树

题目链接 Leetcode.100 相同的树 easy 题目描述 给你两棵二叉树的根节点 p和 q&#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3…

【神经网路】tensorflow实验6--TensorFlow基础

目录 1. 实验目的 2. 实验内容 3. 实验过程 题目一&#xff1a; ① 代码 ② 实验结果 题目二&#xff1a; ① 代码 ② 实验结果 拓展题(选做)&#xff1a; ① 代码 ② 实验结果 4. 实验小结 1. 实验目的 掌握TensorFlow低阶API&#xff0c;能够运用TensorFlow处理数…

让你的作品更出色——词云Word Cloud的制作方法(基于python,WordCloud,stylecloud)

让你的作品更出色—— 词云Word Cloud的制作方法&#xff08;基于python) 本文目录&#xff1a; 一、词云的简介 二、 实现原理和流程 1、制作词云流程图 2、词云实现原理 三、 实现词云的方式 1、安装词云相关模块库 2、WordCloud库 3、stylecloud库 四、总结 一、词…

简单的做一个学校毕业啊项目

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…
最新文章