【数据结构】数据结构

本文是基于中国MOOC平台上,华中科技大学的《数据结构》课程和浙江大学的《数据结构》课程所作的一篇课程笔记,便于后期讲行系统性查阅和复习。

从个人感受而言,华中科技大学的课程讲解更适合初学者(缺点在于,从概念到应用之间的衔接生硬不易懂),浙江大学的课程更适合对基础概念有所了解的初学者(缺点在于,对完全不懂的初学者很不友好)。两个课程搭配学习,有奇效。


一、基础概念

1.1 什么是数据结构

1.1.1 解决问题方法的效率,与什么有关?

解决问题方法的效率,跟数据的组织方式有关。

解决问题方法的效率,跟空间的利用效率有关。

解决问题方法的效率,跟算法的巧妙程度有关。

引入案例:如何在书架上摆放书架?

分析案例:图书的摆放要使得两个操作方便实行

                  1.新书怎么插入?

                  2.怎么找到某本指定的书?

算法一:随便放。

              操作1有空就放,一步到位。操作2需要遍历书架,复杂度高。

算法二:按照书名的拼音字母顺序排放。

              操作1每插入一本新书就要把后面的书进行调整,复杂度高。操作2二分查找。

算法三:分而治之法,书架按块放不同类别的书,每一类里按拼音字母顺序排放。

               操作1先定类别,二分查找位置,移出空位。操作2先定类别,再二分查找。

对比之下,算法三更优。

优化:空间如何分配?类别应该分多细?

解决问题方法的效率,跟数据的组织方式有关。

引入案例:写程序实现一个函数PrintN,使得传入一个正整数为N的参数后,能顺序打印从1到N的全部正整数。

算法一:for循环

void PrintN(int N) {for (int i = 1; i < N + 1; i++) {printf("%d\n", i);}return;
}

算法二:递归函数

void PrintN(int N) {if (N) {PrintN(N - 1);printf("%d\n", N);}return;
}

实际上,在测试代码过程中,N的取值有10、100、1000、10000,而在10、100、1000时两种代码均能跑通。在10000时,递归函数出现了错误,原因是内存不足。

解决问题方法的效率,跟空间的利用效率有关。

引入案例:写程序计算给定多项式在给定点x处的值。

算法一:傻瓜法

double f(int n, double a[], double x) {int i;double p = a[0];for (i = 1; i <= n; i++) p += (a[i] * pow(x, i));return p;
}

算法二:秦久韶算法

double f(int n, double a[], double x) {int i;double p = a[n];for (i = n; i >0; i--) p = a[i - 1] + x * p;return p;
}

对比算法:算法二的运行时间更短。

解决问题方法的效率,跟算法的巧妙程度有关。

1.1.2 什么是数据结构?

 数据结构是数据对象在计算机中的组织方式。

(数据对象的逻辑结构,数据对象在计算机中的物理存储结构)

•数据对象必定与一系列加在其上操作相关联

•实现这些操作所用的方法就是算法。

抽象数据类型

•抽象数据类型是对数据的逻辑描述,而数据结构是对数据的物理描述。抽象数据类型定义了数据的操作和语义,而数据结构实现了这些操作和语义。因此,可以说抽象数据类型是数据结构的一种实现方式。

•数据类型:数据对象集+数据集合相关联的操作集

•抽象:描述数据类型的方法不依赖于具体实现。

(与存放数据的机器无关,与数据存储的物理结构无关,与实现操作的算法编程语言无关)

(只描述数据对象集和相关操作集”是什么“,并不涉及”如何做到“的问题)

1.2 什么是算法

1.2.1 算法的定义

•算法

   •一个有限指令集

   •接收一些输入(有些情况不需要输入),产生输出

   •有穷性:一定在有限步骤之后终止

   •确定性:每一条指令必须有充分明确的目标,不可以有歧义

   •可行性:每一条指令必须计算机能处理的范围之内

   •伪代码:算法描述应不依赖于任何一种计算机语言以及具体的实现手段

1.2.2 什么是好的算法

•衡量好算法的指标:空间复杂度S(n),时间复杂度T(n)。

•在分析一般算法的效率时,经常关注下面两种复杂度:

        1.最坏情况复杂度:T_{_{_{worst}}}(n)

        2.平均复杂度:T_{_{avg}}(n)

通常T_{avg}(n)\leq T_{worst}(n),我们更常用T_{_{_{worst}}}(n)

1.2.3 复杂度的渐进表示 

T(n)=O(f(n))最坏情况复杂度

表示存在常数C>0,n0>0,使得n>=n0时有T(n)\leq C*f(n)

T(n)=Ω(g(n))最好情况复杂度

表示存在常数C>0,n0>0,使得n>=n0时有T(n)\geq C*g(n)

T(n)=Θ(h(n))平均复杂度

表示同时有(n)=O(h(n))和T(n)=Ω(h(n))

 复杂度分析小窍门

•若两段算法分别有复杂度T_{1}(n)=O(f_{1}(n))T_{2}(n)=O(f_{2}(n)),则

 算法相接:T_{1}(n)+T_{2}(n)=max(O(f_{1}(n)),O(f_{2}(n)))

 算法嵌套:T_{1}(n)\times T_{2}(n)=O(f_{1}(n)\times f_{2}(n))

•若T(n)是关于n的k阶多项式,那么T(n)=\circleddash (n^{k})

•一个for循环的时间复杂度=循环次数*循环体代码复杂度

if-else语句的时间复杂度=max{if的条件判断复杂度,if分支的复杂度,else分支的复杂度}

1.3 应用实例

1.3.1 最大子列和问题

问题:给定N个整数的序列{A_{1},A_{2},...,A_{N}},求函数f(i,j)=max{0,\sum_{k=i}^{j}A_{k}}的最大值。

算法一:暴力破解(三个嵌套for循环,复杂度N^{3}T(N)=O(N^{^{3}})

int MaxSubseqSum1(int A[], int N) {int ThisSum=0, MaxSum = 0;int i, j, k;for (i = 0; i < N; i++) {for (j = i; j < N; j++) {for (k = i; k <= j; k++) {ThisSum += A[k];}if (ThisSum > MaxSum) {MaxSum = ThisSum;}}}return MaxSum;
}

算法二:暴力破解改良版(两个嵌套for循环,复杂度N^{2}T(N)=O(N^{^{2}})

int MaxSubseqSum1(int A[], int N) {int ThisSum=0, MaxSum = 0;int i, j, k;for (i = 0; i < N; i++) {for (j = i; j < N; j++) {ThisSum += A[j];if (ThisSum > MaxSum) {MaxSum = ThisSum;}}}return MaxSum;
}

算法三:分而治之(复杂度T(n)=O(N*log(N))

思想上,将大的问题划分为小的块,逐层划分到最小单位。行动上,从最小单位逐层解决问题,直到解决问题。

算法四:在线处理(复杂度T(n)=O(N)

int MaxSubseqSum4(int A[], int N)
{int thissum = 0, maxsum = 0;int i;for (i = 0; i < N; i++){thissum += A[i];if (thissum > maxsum)maxsum = thissum;else if (thissum < 0)thissum = 0;}return maxsum;
}

二、线性结构 

2.1 线性表及其实现

2.1.1 线性表的概念

线性表的定义

•线性表是一种数据结构,是由n(n≥0)个数据元素(a1,a2,…,an)构成的有限序列。

记作:L=(a1,a2,…,an)

a1——首元素,an——尾元素

•表的长度(表长)——线性表中数据元素的数目。

•空表——不含数据元素的线性表。

•对于线性表L=(a1,a2,…,a(i-1),ai,a(i+1),...,an),前驱和后驱:

  a(i-1)在ai之前,称a(i-1)是ai的直接前驱(1<i≤n)

  a(i+1)在ai之后,称a(i+1)是ai的直接后继(1≤i<n)

  a1没有前驱,an没有后继

  ai(1<i<n)有且仅有一个直接前驱和一个直接后继

常见线性表举例

•字母表:L1=(A,B,...,Z),表长为26

•姓名表:L2=(李明,翠菊,方宏名,王林)表长为4

•表格

2.1.2 线性表的基本操作 

线性表的基本操作函数

IniList(&L)//构造空表LListLength (L)//求表L的长度GetElem(L,i,&e)//取元素ai,由e返回aiPriorElem(L,ce,&pre_e)//求ce的前驱,由pre_e返回InsertElem(&L,i,e)//在元素ai之前插入新元素eDeleteElem(&L,i)//删除第i个元素EmptyList(L)//判断L是否为空表

删除操作:DeleteElem(&L,i)

1.删除表中的第i个数据元素(1\leq i\leq n),记作DeleteElem(&L,i)

   即删去表中第i个元素a_{i}

   (a_{1},a_{2},...,a_{i-1},a_{i},a_{i+1},...,a_{n})——>(a_{1},a_{2},...,a_{i-1},a_{i+1},...,a_{n})

2.指定元素值x,删除表L中的值为x的元素,记作:DeleteElem(&L,x)

   即删去表中值为x的元素。若a_{i-1}=x,则

   (a_{1},a_{2},...,a_{i-1},a_{i},a_{i+1},...,a_{n})——>(a_{1},a_{2},...,a_{i},a_{i+1},...,a_{n})

插入操作:InsertElem(&L,i,e)

在元素ai之前插入新元素e(1<=i<=n+1),记作: InsertElem(&L,i,e)

(a_{1},a_{2},...,a_{i-1},a_{i},a_{i+1},...,a_{n})——>(a_{1},a_{2},...,a_{i-1},e,a_{i},a_{i+1},...,a_{n})

查找操作: 确定元素值(或数据项的值)为e的元素。

给定:L=(a1,a2,.….,ai,….,an)和元素e

若有一个ai=e,则称“查找成功”(i=1,2,…n);否则,称“查找失败”。

排序操作:按元素值或某个数据项值的递增(或递减)次序重新排列表中各元素的位置。

例:排序前:L=(90,60,80,10,20,30)

       排序后:L=(10,20,30,60,80,90)

       L变为有序表

 合并操作:将有序表L_{_{a}}L_{b}合并为有序表L_{c}

例:设有序表:La=(2,14,20,45,80)

                         Lb=(8,10,19,20,22,85,90)

           合并为表Lc=(2,8,10,14,19,20,20,22,45,80,85,90)

复制操作:将表L_{_{a}}复制为表L_{b}L_{b}

 

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

2024-01-06-AI 大模型全栈工程师 - 机器学习基础

摘要 2024-01-06 阴 杭州 晴 本节简介: a. 数学模型&算法名词相关概念; b. 学会数学建模相关知识&#xff1b; c. 学会自我思考&#xff0c;提升认知&#xff0c;不要只会模仿&#xff1b; 课程内容 1. Fine-Tuning 有什么作用&#xff1f; a. 什么是模型训练&#xff…

redis的主从配置模拟(一主双从)

目录 先来给大家扩展机道面试官经常会问到关于redis的题 一、redis有哪些好处 二、redis相比memcached有哪些优势 三、redis常见性能问题和解决方案 四、redis集群的工作原理 五、redis主从的原理 redis的主从配置模拟&#xff08;一主双从&#xff09; 一、准备环境 …

TCP 传输控制协议——详细

目录 1 TCP 1.1 TCP 最主要的特点 1.2 TCP 的连接 TCP 连接&#xff0c;IP 地址&#xff0c;套接字 1.3 可靠传输的工作原理 1.3.1 停止等待协议 &#xff08;1&#xff09;无差错情况 &#xff08;2&#xff09;出现差错 &#xff08;3&#xff09;确认丢失和确认迟到…

JetpackCompose之状态管理

JetPack Compose系列&#xff08;13&#xff09;—状态管理 State 即&#xff0c;状态。官方的解释是&#xff1a; State in an application is any value that can change over time. And ****event can notify a part of a program that something has happened. 可以这样…

113.路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum 22 输出&a…

cleanmymacX和腾讯柠檬哪个好用

很多小伙伴在使用Mac时&#xff0c;会遇到硬盘空间不足的情况。遇到这种情况&#xff0c;我们能做的就是清理掉一些不需要的软件或者一些占用磁盘空间较大的文件来腾出空间。我们可以借助一些专门的清理工具&#xff0c;本文中我们来推荐几款好用的Mac知名的清理软件。并且将Cl…

【Git】Windows下通过Docker安装GitLab

私有仓库 前言基本思路拉取镜像创建挂载目录创建容器容器启动成功登录仓库设置中文更改密码人员审核配置邮箱 前言 由于某云存在人数限制&#xff0c;这个其实很好理解&#xff0c;毕竟使用的是云服务器&#xff0c;人家也是要交钱的。把代码完全放在别人的服务器上面&#xf…

百家cms代审

环境搭建 源码链接如下所示 https://gitee.com/openbaijia/baijiacms 安装至本地后 直接解压到phpstudy的www目录下即可 接下来去创建一个数据库用于存储CMS信息。&#xff08;在Mysql命令行中执行&#xff09; 接下来访问CMS&#xff0c;会默认跳转至安装界面 数据库名称和…

114.乐理基础-五线谱-快速识别五线谱的谱号

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;113.乐理基础-五线谱-五线谱的调号&#xff08;二&#xff09;-CSDN博客 15个调号&#xff0c;如下图&#xff0c;该怎样才能随便拿出一个来就能快速的知道这是什么调号呢&#xff1f; 一共分为三个要点&#xff1…

单片机学习笔记---DS1302时钟

上一节我们讲了DS1302的工作原理&#xff0c;这一节我们开始代码演示。 新创建一个工程写上框架 我们需要LCD1602进行显示&#xff0c;所以我们要将LCD1602调试工具那一节的LCD1602的模块化代码给添加进来 然后我们开始创建一个DS1302.c和DS1302.h 根据原理图&#xff0c;为了…

牛客网SQL进阶114:更新记录

官网链接&#xff1a; 更新记录&#xff08;二&#xff09;_牛客题霸_牛客网现有一张试卷作答记录表exam_record&#xff0c;其中包含多年来的用户作答试卷记录&#xff0c;结构如下表。题目来自【牛客题霸】https://www.nowcoder.com/practice/0c2e81c6b62e4a0f848fa7693291d…

肯尼斯·里科《C和指针》第13章 高级指针话题(2)函数指针

我们不会每天都使用函数指针。但是&#xff0c;它们的确有用武之地&#xff0c;最常见的两个用途是转换表(jump table)和作为参数传递给另一个函数。本节将探索这两方面的一些技巧。但是&#xff0c;首先容我指出一个常见的错误&#xff0c;这是非常重要的。 简单声明一个函数指…

【MATLAB源码-第138期】基于matlab的D2D蜂窝通信仿真,对比启发式算法,最优化算法和随机算法的性能。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 D2D蜂窝通信介绍 D2D蜂窝通信允许在同一蜂窝网络覆盖区域内的终端设备直接相互通信&#xff0c;而无需数据经过基站或网络核心部分转发。这种通信模式具有几个显著优点&#xff1a;首先&#xff0c;它可以显著降低通信延迟&…

铱塔 (iita) 开源 IoT 物联网开发平台,基于 SpringBoot + TDEngine +Vue3

01 铱塔 (iita) 物联网平台 铱塔智联 (open-iita) 基于Java语言的开源物联网基础开发平台&#xff0c;提供了物联网及相关业务开发的常见基础功能, 能帮助你快速搭建自己的物联网相关业务平台。 铱塔智联平台包含了品类、物模型、消息转换、通讯组件&#xff08;mqtt/EMQX通讯组…

1、 快速上手 [代码级手把手解diffusers库析]

快速上手Pipeline 内部执行步骤后续更新计划 diffusers是Hugging Face推出的一个diffusion库&#xff0c;它提供了简单方便的diffusion推理训练pipe&#xff0c;同时拥有一个模型和数据社区&#xff0c;代码可以像torchhub一样直接从指定的仓库去调用别人上传的数据集和pretrai…

Linux中ps/kill/execl的使用

ps命令&#xff1a; ps -aus或者ps -ajx或者 ps -ef可以查看有哪些进程。加上 | grep "xxx" 可以查看名为”xxx"的进程。 ps -aus | grep "xxx" kill命令&#xff1a; kill -9 pid 杀死某个进程 kill -l 查看系统有哪些信号 execl函数&#…

RocketMQ(二):领域模型(生产者、消费者)

1 生产者&#xff08;Producer&#xff09; 本节介绍Apache RocketMQ 中生产者的定义、模型关系、内部属性、版本兼容和使用建议。 1.1 定义 生产者是Apache RocketMQ 系统中用来构建并传输消息到服务端的运行实体。 生产者通常被集成在业务系统中&#xff0c;将业务消息按照要…

C++基础入门之引用

目录 一.引用 1.1引用和取地址 1.2 别名和原名的区别 1.3 引用的用法 1.31 做参数 1.311 输出型参数&#xff1a;形参改变实参 1.312 可以减少拷贝&#xff0c;增加效率 1.32 引用的约定 1. 引用必须初始化 2. 引用定义后&#xff0c;不能改变指向 4. 给指针取别名 1.33…

【Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)】

Linux环境基础开发工具的使用yum、vim、gcc、g、gdb、make/Makefile Linux软件包管理器- yumLinux下安装软件的方式认识yum查找软件包安装软件如何实现本地机器和云服务器之间的文件互传卸载软件 Linux编辑器 - vimvim的基本概念vim下各模式的切换vim命令模式各命令汇总vim底行…

聊聊JIT优化技术

&#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是小徐&#x1f947;☁️博客首页&#xff1a;CSDN主页小徐的博客&#x1f304;每日一句&#xff1a;好学而不勤非真好学者 &#x1f4dc; 欢迎大家关注&#xff01; ❤️ 我们知道&#xff0c;想要把高级语言转变成计算…