数据结构杂谈(一)

在你点进来这里的一瞬间,欢迎你找到了宝藏

这是一些关于数据结构和算法里最详细的阐述和学习心得,我十分乐意和你分享这些知识。

如果你已经看完这篇杂谈,可以前往下一篇→数据结构杂谈(二)_尘鱼好美的小屋-CSDN博客

1 绪论

1.1 什么是数据结构

数据结构是一门研究非数值计算的程序设计问题中计算机操作对象以及它们之间关系和操作的学科。

1.2 基本概念和术语

数据:数据是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。

数据元素:是数据的基本单位(相当于数据库的元组),数据元素在计算机程序中通常作为一个整体进行考虑和处理,也简称为元素,或称为记录、结点或顶点;一个数据元素由若干个数据项组成。

在数据库原理中,层次模型采用的就是记录,也就是关系数据库中所说的元组。从中我们可以理解了,某一个类的实例就是数据元素。

数据项:构成数据元素的不可分割的最小单位

相当于数据库中的属性;在数据库中我们也曾叫作数据项。

数据对象:是性质相同的数据元素的集合,是数据的一个子集,在不产生混淆的情况下,我们一般把数据对象简称为数据

数据结构:数据元素不是孤立存在的,它们之间存在着某种关系,数据元素相互之间的关系称为结构。

在看完以上的概念后,我想我有必要来说几句。

我们可以举生活中的例子来说明以上的概念。假设我们把人看成数据(数据对象),而把小红小明看成数据元素,把小红小明等人的性别、学号、年龄看成数据项,如果我们要把小红小明等人按照一定的规则放在一起,这个规则就叫数据结构

对于数据结构来说包含以下三个方面的内容

  1. 数据元素之间的逻辑关系,也称为逻辑结构
  2. 数据元素及其关系在计算机内存中的表示(又称为映像),称为数据的物理结构或数据的存储结构
  3. 数据的运算和实现,即对数据元素可以施加的操作以及这些操作在相应的存储结构上的实现。

1.2.1 数据结构的两个层次

数据结构分为逻辑结构物理结构,兹分别列举如下:

逻辑结构物理结构(存储结构)
描述数据元素之间的逻辑关系数据元素及其关系在计算机存储器中的结构(存储方式)
和数据的存储无关,独立于计算机是数据结构在计算机中的存储形式
是从具体问题抽象出来的数学模型

1.2.2 逻辑结构的种类

对于逻辑结构来说,有两种划分方式:

划分方法一

结构划分说明
线性结构有且仅有一个开始和一个终端结点,并且所有结点都最多只有一个直接前驱和一个直接后继。例如:线性表,栈,队列,图
非线性结构一个结点可能有多个直接前驱和直接后继。例如:树,图

划分方法二:

结构划分说明
集合结构结构中的数据元素直接除了同属于一个集合的关系外,无任何其他关系
线性结构结构中的数据元素之间存在着一对一的线性关系
树形结构结构中的数据元素之间存在着一对多的层次关系
图状结构或网状结构结构中的数据元素之间存在着多对多的任意关系

1.2.3 四种基本的存储结构

我们可以把存储结构划分为四种,兹列举如下:

结构划分说明
顺序存储结构用一组连续的存储单元一次存储数据元素,数据元素之间的逻辑关系由元素的存储位置来表示
链式存储结构用一组任意的存储单元存储数据元素,数据元素之间的逻辑关系用指针来表示
索引存储结构在存储结点信息的同时,还建立附加的索引表
散列存储结构根据结点的关键字直接计算出该结点的存储地址

C语言中用数组来实现顺序存储结构

C语言中用指针来实现链式存储结构

从上面的简洁的总结来看,我们如何更好地理解这些数据结构呢?实际上,逻辑结构指的是数据元素之间的关系,如果拿数据库中类比的话,就是你要用层次数据模型还是用关系数据模型来表示数据的区别。而物理结构指的是数据在电脑上面存放的形式,有的是整整齐齐连续排列在内存中,有些是不连续地排列在内存中。

而之所以出现这两种结构,是因为实际业务的需要,你想想看,如果使用连续的内存(顺序存储结构)来存储数据,万一你频繁地删除数据,而且考虑最坏情况,刚好删掉第二个数据元素,那么假设总共由n个数据元素的话,那么后面就有n-2个数据元素需要前移,十分麻烦。

但是如果用不连续存储(链式存储结构)就不一样了,链式存储结构采用的是一种寻址的方式,即数据元素能够寻找上一个数据元素的地址。这样的话如果频繁做更改,拿删除来说,只需要把一个数据元素删除,然后前后的数据元素地址改动一下即可,当然,这些操作都是有小细节的,这里只是大概提一下罢了。

逻辑结构是面向问题的,而物理结构是面向计算机的,其基本的目标就是将数据及其逻辑关系存储到计算机的内存中。

1.2.4 数据类型和抽象数据类型

数据类型:是一组性质相同的值的集合以及定义在这个值集上的一组操作的总称

抽象数据类型(Abstract Data Type,ADT):是指一个数学模型以及定义在该模型上的一组操作。

抽象数据类型的说明

  • 由用户定义,从问题抽象出数据模型。(逻辑结构)
  • 还包括定义在数据模型上的一组抽象运算。(相关操作)
  • 不考虑计算机内的具体存储结构和运算的具体实现算法

抽象数据类型的定义格式

ADT 抽象数据类型名{数据对象:<数据对象的定义>数据关系:<数据关系的定义>基本操作:<基本操作的定义>
}ADT 抽象数据类型名

基本操作的定义格式

基本操作名<参数表>初始条件:<初始条件描述>操作结果:<操作结果描述>

说明

  1. 参数表:参数表中引用参数以&开头,表示不仅可以作为参数输入值,还能返回操作后的结果。
  2. 初始条件:描述操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应的,并返回相应出错信息。若初始条件为空,则省略
  3. 操作结果:说明操作正常完成之后,数据结构的变化状况和返回的结果。

数据类型的出现不是偶然而是必然,如果不规定数据类型的话,那么就会造成资源的浪费。拿C语言来举例,如果你不使用int,long这些基本数据类型的话,那么无端给出一个7,谁知道你的7占几个字节?好比住房子,诶,当然,如果你想提前举手:住房子当然是越大越好啦,那国家可就不同意了,你住那么大,别人住哪里?所以,根据公民的所需来规定每个公民住所的大小,对应到C上,每个数据都应该有自己在内存中所占的对应大小。故数据类型出现了。

那么抽象数据类型又是怎么出现的呢?我们试想,如果要对两个整数做加法,我们关心的是哪两个整数,它们做的操作是不是加法,它们做出来的结果如何。而不关心它们在计算机的时候用到计算机的底层逻辑,比如动到了哪里的内存,CPU做了什么工作,这通通都是我们不关心的,由此抽象数据类型应运而生了。

抽象是指抽取出实物具有的普遍性的性质。它是抽出问题的特征而忽略非本质的细节,是对具体事物的一个概括。抽象是一种思考问题的方式,它隐藏了繁杂的细节,只保留实现目标所需要的信息;如果你学过java,你就知道里面的抽象类深谙此道理。

1.3 算法的基本概念

1.3.1 算法和算法分析

1.3.1.1 引入

我们首先写一个求和算法出来,如下:

int sum = 0;
for(int i = 1;i<=100;i++)
{sum = sum + i;
}
cout << "100 = "<<sum<<endl;

上面我想大多数人从上大学第一门课程C语言开始学的就是这个求和算法。可以我们可以看到,这个算法是采用for循环来设计的;在深度学习中,for循环是效率最低的顺序扫描,所以在不得已的情况下,我们不会采用for循环。那我们有更好地求和方法吗?

在高中的时候,我们曾经学过倒序相加法,值得一提的是,倒序相加法现在没几个人记得,为啥?因为它们根本不理解其中的原理,而是靠大量的题目堆出来的记忆,所以在这里,我讲一下倒序相加法的由来。

大名鼎鼎数学家高斯在很小的时候就因为老师刁难的一道题很闻名,老师故意刁难1加到100要让还在上小学的高斯做出来,而高斯花的时间也不多,三下五就做出来了,他是这么做的:既然要算1加到100,那么我再搞一个1加到100,但是是倒序排放,那么上面的1和下面的100相加刚好为101,2和99相加为101,以此类推总共有100个101,也就是10100,那么除以二就是1加到100的结果,即5050。

如果把100看成n,我们可以写出下列的程序:

int i = 0;
int sum = 0;
int n = 100;
sum = (1+n)*n/2;
cout<<sum<<endl;

由此我们可以发现,好的算法可以起到事半功倍的效果。由此我们引出算法的定义,算法是什么?

1.3.1.2 算法

算法:是对特定问题求解步骤的一种描述

弄懂了算法的概念,那么算法和程序有什么区别呢?

算法是解决问题的一种方法或一个过程,考虑如何将输入转换成输出,一个问题可以有多种算法;而程序是用某种设计语言对算法的具体实现。

对于算法来说有几大特性,如下所示:

特性说明
有穷性一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。
确定性算法中的每一条指令必须有确切的含义,没有二义性,在任何条件下,只有唯一地一条执行路径,即对于相同的输入只能得到相同的输出
可行性一个算法是能行的,即算法种描述的操作都是可以通过已经实现的基本运算执行有限次来实现的
输入一个算法可以有零个或多个输入
输出一个算法可以有一个或多个输出

在给出上面算法的特性后,我们来避免记忆,给出一个比较简单的故事,假如你的算法是无穷步,那还有意义吗?本来人们就是用来解决问题,不能解决问题要这个算法有什么用。每个算法的每个步骤都是确定的,也就是说不会出现二义性。也就是说,你不能说输出1然后会出来两个数。并且你的算法做出来要可行,如果你的算法开销太大,以现有的机器根本跑不出来,那这个算法也是没有什么意义的。当然,一个算法可以没有输入,但是不能没有输出,就比如我们最简单的每个编程教材最开始都有的一个案例:hello world

1.3.1.3 衡量算法

对于算法设计我们应该有如下要求:

要求说明
正确性算法应当满足具体问题的需求
可读性算法要方便人对算法的理解
健壮性(鲁棒性)算法能应对非法情况
高效性要求花费尽量少的时间和尽量低的存储需求

一个好的算法首先要具备正确性,然后是健壮性,可读性,在几个方面都满足的情况下,主要考虑算法的效率,通过算法的效率高低来评判不同算法的优劣程度。算法效率从以下两个方面来考虑:

算法效率说明
时间效率指的是算法所耗费的时间
空间效率指的是算法执行过程中所耗费的存储空间

时间效率和空间效率有时候是矛盾的,有时候为了提高时间效率,不得已要牺牲空间效率;所以为了提升总体效率,我们要折中选择。

算法时间效率可以用依据该算法编制的程序在计算机上执行所消耗的时间来度量。

对于一个算法的度量,我们有下面两种方法:

**事后统计:**将算法实现,测算其时间和空间开销。

事前分析:对算法所消耗资源的一种估算方法

事后统计一般就像马后炮,所以我们一般采用事前分析

1.3.2 函数的渐近增长

输入规模n在没有限制下,只要超过一个数值N,这个函数就总是大于另一个函数,我们则称函数是渐进增长的。即:给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的n>N,f(n)总是比g(n)大,那么,我们说f(n)的增长渐进快于g(n)

image-20220112103017247

1.4 算法的时间复杂度

1.4.1 渐进时间复杂度

渐进时间复杂度:若有某个辅助函数f(n),使得当n趋于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n) = O(f(n)),称O(f(n))为算法的渐进时间复杂度(O是数量级的符号),简称时间复杂度

定义里用大写O来体现算法时间复杂度的记法,我们称之为大O记法。一般情况下,不必计算所有操作的执行次数,而只考虑算法中基本操作执行的次数,它是问题规模n的某个函数,用T(n)表示。而为了便于比较不同算法的时间效率,我们仅比较它们的数量级。

1.4.2 推导大O阶的方法

指路:大O阶推导方法

1.4.3 常见的时间复杂度

1.4.3.1 算法时间效率的比较

当n取得很大时,指数时间算法和多项式时间算法在所需时间上非常悬殊。

image-20211002112258937

实际上下面的表不用记,只需要利用高数的函数图形去理解就行。

1.4.3.2 三种复杂度

**最坏时间复杂度:**考虑输入数据“最坏”的情况。

平均时间复杂度:考虑所有输入数据都等概率出现的情况。

**最好时间复杂度:**考虑输入数据“最好”的情况。

一般总是考虑在最坏情况下的时间复杂度,以保证算法的运行时间不会比它更长。

对于复杂的算法,可以将它分成几个容易估算的部分,然后利用大O加法法则和乘法法则,计算算法的时间复杂度。

**加法规则:**T(n) = T1(n)+T2(n) = O(f(n))+O(g(n)) = O(max(f(n),g(n)))

**乘法规则:**T(n) = T1(n)T2(n) = O(f(n))O(g(n)) = O(f(n)g(n))

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算器排html页面,htmltest~计算器界面的实现

通过divcss和部分布局的作用&#xff0c;实现了&#xff0c;如下效果的计算器展示页面![C%]R$IGDK4J(%3LJXD3]SY.png&#xff0c;废话不多说&#xff0c;最主要的还是分享代码&#xff1a;html&#xff1a;Title.计算器-口 X编辑(E)查看(V)帮助(H)BackspaceCECMC789/sqrtMR456*…

git 常用方法

1.删除远程tag或者branchgit push origin --delete (tagName)/(brachName).例如&#xff1a;删除远程2.1branch&#xff1a;git push origin --delette 2.12.检出某次commit时的代码&#xff08;通过commit index检出&#xff09;git checkout commit的SHA1值例如&#xff1a;g…

win7 git 添加 ssh key

分两步走&#xff0c;借助git bash客户端&#xff1a;第一步&#xff1a;生成秘钥创建SSH key. 在用户主目录下&#xff0c; 看看有没有.ssh目录&#xff0c; 如果有&#xff0c; 再看看这个目录下有没有id_rsa 和 id_rsa.pub 这两个文件&#xff0c; 如果已经有了&#xff0c;…

解决三星手机EditText背景色的问题

问题描述android:background"#ffffff"其他手机手机背景都是白色&#xff0c;三星却是黑色的。怎么办 解决方案1写个主题测试下 解决方案2检查是三星的手机换背景色解决方案3你自己设置下edittext的背景就好了 解决方案4三星手机没这bug&#xff0c;你的固件不是正常的…

操作系统随笔(二)

如果你还没有读过第一篇随笔&#xff0c;请点击这里→操作系统随笔&#xff08;一&#xff09; 文章目录[toc]2 进程和线程2.1 进程2.1.1 进程模型2.1.2 进程的创建2.1.3 进程的终止2.1.4 进程的层次结构2.1.5 进程的状态2.1.6 进程的实现2.2 线程2.2.1 进程的使用2.2.2 经典的…

golang实现常用数据结构

2019独角兽企业重金招聘Python工程师标准>>> 1.数组栈的实现 package mainimport ( "fmt")type ItemType inttype Stack struct { node [10]ItemType maxsize int top int}func StackInit(p *Stack) { p.top -1}func StackCheckFull(p *Stack) bo…

html label修改字体颜色,Swift label文字显示不同颜色(字体)

根据 Stack Overflow 上的这篇文章 大概有三种方法:1. 先设置整个 text 为 NSMutableAttributedString, 再使用 Range 设置要改变颜色(字体)的文本var myString:NSString "I AM KIRIT MODI"var myMutableString NSMutableAttributedString()In ViewDidLoadoverride…

【问题解决】无法创建新的堆栈防护页面

【问题发现】 项目中需要几个自定义的控件,菜鸟D定义了一个接口,打算使用多态来统一调用。在完成两个自定义控件后&#xff0c;项目都能正常运行。但是在第三个控件使用的时候就出了问题&#xff1a;将控件拖到界面上以后&#xff0c;不能拖动改变控件的宽度&#xff0c;一拖动…

html里空间顺序,按空间顺序写我的房间作文

导语&#xff1a;人人的房间都是不一样的&#xff0c;因为每个人都有自己独特的性格和思想。下面是由小编整理的关于按空间顺序写我的房间作文。欢迎阅读&#xff01;篇一&#xff1a;我的房间作文(按空间顺序)我的房间在客厅的东面&#xff0c;床的右侧是一面窗户&#xff0c;…

一分钟了解阿里云产品:RDS概述

下面我们来介绍下阿里云的云数据库&#xff08;Relational Database Service&#xff0c;简称RDS&#xff09;这款产品。一起来学习下吧。 那么&#xff0c;RDS是什么呢&#xff1f;简单来说&#xff0c;它是一种稳定可靠、可弹性伸缩的在线数据库服务。 RDS基于飞天分布式系统…

Python速忆笔记(更新中)

你好&#xff0c;如果你是第一次看我的笔记&#xff0c;欢迎您关注我&#xff0c;我喜欢持续分享更多有意思的干货。如果能够帮到您的话&#xff0c;希望你给我点个赞❤️ 文章目录1.1 快速回忆1.1.1 打印和注释1.1.1.1 打印1.1.1.2 注释1.1.2 字符串1.1.2.1 概述1.1.2.2 拼接1…

读书

博客注册有一段时间了&#xff0c;但是一直没开张。冒着虽然写东西也还是会长草的危险&#xff0c;我还是先贴几个字吧&#xff0c;一方面是好歹给自己一个开始&#xff0c;一方面也是有人想看。其实后者更重要&#xff0c;这个跟我们写代码很像&#xff0c;很多时候你关注一些…

java及python调用RabbitMQ

1,python调用MQ发送消息(生产者),话不多说,直接上干货 import pika 如下图 2.java调用MQ发送消息(生产者) 具体代码如下: python 的代码如下 connection pika.BlockingConnection(pika.ConnectionParameters(IP,端口,/))channel connection.channel()msg_props pika.Bas…

android模块化 osgi,蚂蚁金融级移动应用 osgi 模块化架构实践.pdf

蚂蚁金融级移动应用 osgi 模块化架构实践To p 1 0 0 C a s eS t u d i e s O f T h e Ye a r s-AndroidTo p 1 0 0 C a s eS t u d i e s O f T h e Ye a r s1“Application” App“Service”2BundleComponent3MultiDexTo p 1 0 0 C a s eS t u d i e s O f T h e Ye a r s-300…

MySQL速忆笔记(更新中)

本笔记不适合初学者观看&#xff0c;如果想细致了解数据库的初学者可以前往数据库杂谈全集深入了解。 数据库原理指路&#xff1a;数据库杂谈&#xff08;一&#xff09; 另外希望能看到这篇笔记的同志能点个赞&#xff0c;在内卷的时代分享知识不容易。 文章目录[toc]1 准备工…

svn上传报Authorization failed错误解决办法

svn上传文件时没有弹出用户登录界面&#xff0c;而是直接报Authorization failed错误。出现该问题基本都是三个配置文件的问题&#xff0c;下面把这个文件列出来 svnserve.conf配置文件中的 [general] anon-access read auth-access write password-db passwd authz-db aut…

html知识收集(一)

1.页内跳转iframe <ul> <li><a href"1.html" target"iframe1">1</a></li> <li><a href"2.html" target"iframe1">2</a></li> </ul> </ul> <iframe name"i…

html5怎么调用手机陀螺仪,html5 获取 陀螺仪,重力感应(转发)

DeviceOrientationEvent是获取方向&#xff0c;得到device静止时的绝对值&#xff1b;DeviceMotionEvent是获取移动速度&#xff0c;得到device移动时相对之前某个时间的差值比设备定位API&#xff0c;该API允许你收集设备的方向和移动信息。此外&#xff0c;该API只在具备陀螺…

设定Word段落的背景色

段落背景不同于文字区别。很多新接触word的朋友都找不到怎么弄。 先把光标停留在需要设置的段落文字上&#xff0c;或者选择需要设置的段落文字。 点击段落里的边框和底纹&#xff0c;如图 在弹出框中选择底纹。 选择需要填充的颜色&#xff0c;在左下角处把文字切换成段落。…

Hadoop随笔(二)

文章目录[toc]2 Hadoop概念2.1 Hadoop简介2.2 MapReduce编程模型简介2.3 Hadoop系统的组成2 Hadoop概念 面对大数据量的处理需求&#xff0c;一个常用的方法就是把它们分割成互不依赖的小份数据来分别计算处理&#xff0c;这就是所谓的单指令多数据流(SIMD)的数据计算模式。Ha…