浅谈数据结构与算法

2023-10-31

1.什么是数据结构?

答:存储、组织数据的方式。数据的种类有很多:字符串、整数、浮点、...

组织各种数据的方式:即数据元素之间的关系:列表、字典、元组、...

举例:

列表方式: [老王,18,男]

字典方式:{name:"老王",age:18,sex:"男"}

综合方式:[{name:"老王",age:18,sex:"男"},{name:"老李",age:19,sex:"男"}]

{老王:{age:18,sex:"男"},老李:{age:19,sex:"男"}}

数据的结构有两种形式:

物理形式:顺序表、链表

逻辑形式:集合、线性、树形、图形

2.算法是什么?

为了实现业务目的各种分析方法和思路就是算法

公司的核心:数据

数据的存储:数据结构:

存储数据的目的:提供信息和解决问题

算法复杂度:

时间复杂度:代码执行需要的计算工作量

空间复杂度:代码运行需要的内存空间

业务数据:

    用户访问业务时候,产生的信息内容

数据结构:

    静态的描述了数据元素之间的关系

算法:

    解决各种实际问题的方法和思路

数据结构 + 算法 = 程序

抽象数据类型(Abstract Data Type)

抽象数据类型(ADT)的含义是指一个数学类型以及定义在此数学类型上的一组操作。即把数据类型和数据类型上的运算捆在一起,进行封装。

引入抽象数据类型的目的:

是把数据类型的表示和运算的实现与这两者在程序中的引用隔开,使它们相互独立。

简单来说:就是把数据带入场景,让他们“有意义”

常见数据运算类型:

插入、删除、修改、查找、排序,即所谓的“增删改查”

 

思路总结:算法特性

1、输入: 算法具有0个或多个输入

2、输出: 算法至少有1个或多个输出

3、有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成

4、确定性:算法中的每一步都有确定的含义,不会出现二义性

5、可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成

算法的评判标准:

问:为什么不一样?哪个方法好,时间慢的方法就好么?

答:1、因为不一样,所以不一样。

2、不一定

计算依赖于服务器环境,环境不唯一,所以用时间来评判,不准确。

问: 如何综合评判两种方法?

分析:至少把代码运行的环境因素抛离出去,就剩下代码本身,代码本身使我们解决思路的实现,也就是算法

那么我们应该怎么评判算法呢?:

答:代码量太大,没办法整体分析,我们就拆,拆到我们能接收的方式来分析:

评判一个算法是否优秀,我们应该从两个方面来思考方法的优劣:

步骤数量和单位时间

问:步骤数量和单位时间的关系?

步骤数量 * 单步执行时间 == 代码执行总时间

1、算法特性:量入出题题能解,行有意步步可为

2、算法的评判标准:步骤数量+单位时间

时间复杂度的6条基本计算规则

1、基本操作,即只有常数项

简单来说:没有数量规模,就执行一次

时间复杂度:O(1)

2、顺序结构,时间复杂度按加法进行计算

简单来说:一步一步的执行下去,类似上面的方法二

时间复杂度:O(n)                                                                                                

3、循环结构,时间复杂度按乘法进行计算

循环:就是批量执行多次,类似上面的方法一:

时间复杂度:O(n3)

4、分支结构,时间复杂度取最大值

简单来说:就是多分支if语句,找一个时间最长的作为标准的时间

5、判断一个算法的效率时,往往需要关注操作数量的最高,其它次要项和常数项可以忽略

6、在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度

常见时间复杂度及函数样式

注意:

2m = n,知道n的值,求m,

m=log2n 而我们经常将log2n(以2为底的对数)简写成logn

所消耗的时间从小到大

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)

简单来说:数字最小,n越多,值越大

时间复杂度越,效率越,时间越

timeit模块

timeit模块可以用来测试一小段Python代码的执行速度。

核心代码1介绍

class timeit.Timer(stmt='pass', setup='pass', timer=<timer function>)

代码详解:

Timer是测量小段代码执行速度的类。

stmt参数是要测试的代码语句(statment)

例子:测试某个函数,函数代码用"func()"表示

setup参数是运行代码时需要的设置;

例子:测试当前文档的func模块,使用 "from __main__ import func"

timer参数是一个定时器函数,与操作系统平台有关,一般省略。

示例:

timer1 = timeit.Timer("T1()","from __main__ import T1")

核心代码2介绍

timeit.Timer.timeit(number=1000000)

代码详解:

Timer类中测试语句执行速度的对象方法。

number参数是测试代码时的测试次数,默认为1000000次。

timeit方法返回执行代码的总共耗时,它是一个float类型的秒数。

简写方法:测试代码.timeit(1000000)

示例:

timer1.timeit(number=1000) 简写 timer1.timeit(1000)

timeit模块使用原则:生成测试对象,测试效果

数据结构 进阶

线性表简介:

顾名思义:就是将一大堆同类型的数据,按照某种关系,依次排列出来,就形成了一条线。

特点:数据之间,只有前后关系。

举例:

100 200 300 400 ...... n

线性表是最基本,也使用最广的数据结构之一,常被用作更复杂的数据结构的实现基础。

线性表分类:

根据线性表的实际存储方式,分为两种常见的模型:

顺序表:

将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。

链表:

将元素存放在通过链接构造起来的一系列存储块中。也就是说,这种表不但有自己的数据信息,也有下一个数据结点的地址信息

链表有如下分类:单向链表、双向链表、单向循环链表

顺序表两种形式:

基本布局 + 元素外置

基本布局存储同类数据

元素外置存储异类数据

a)基本布局:

简单来说,就是存储多个同类型的数据,每个数据占用一个固定存储空间,多个数据组合在一块的时候,物理地址就会连续起来

b) 元素外置

元素外置,适用于存储不同类型的数据A-D,因为不同类型数据的占用存储空间不一样,不能按照基本布局的方式来存储。

通过比较发现,虽然他们数据占用的空间不一致,但是他们的逻辑地址编号都是同一的数据类型,所以存储他们的时候,可以单独申请一块连续空间,来存储A-D数据的逻辑地址。

图b这样的顺序表,因为顺序表B内存储的是上面顺序表A的逻辑地址数值,通过存储的逻辑地址,找到真正存储数据的地址,所以顺序表B中的数值也被称为对实际数据的索引,这是最简单的索引结构。

顺序表结构

现在我们介绍一下顺序表的结构

顺序表结构

通过上图的介绍,我们可以知道顺序表由两部分组成:基本信息+存储元素。

因为顺序表有两中表现形式,所以就出现了两种表现形式:

基本布局:一体式结构

元素外置:分离式结构

 

整合式 或 一体式

一体式结构:

存储表信息与元素存储区以连续的方式安排在一块存储区里,形成一个完整的顺序表对象。

 

一体式特点:

因为整体,所以易于管理,顺序表创建后,元素存储区就固定了。

 

分离式

分离式结构:

顺序表对象里保存基本信息(地址容量+元素个数)和元素存储空间的一个逻辑地址(A),通过逻辑地址(A)找到真正的数据存储地址。

 

分离式特点:

因为分离,所以灵活,元素的存储空间可以灵活调整

---------

3.2.3 顺序表实践

我们在设定数据表的时候,会首先申请我要使用的存储空间。而存储空间中的数据不是一成不变的,接下来我们来介绍一下元素存储内容变化时候顺序表的变化。

存储内容的变化,无非是少或多,少会造成存储空间的浪费,多的话,存储空间就会发生变化。我们接下来主要是对存储内容更改或者存储内容大于计划空间的这两种情况进行分析。

 

内容更改

一体式:

因为一体式,基本信息和存储元素是一个整体的对象,而且一旦定义,就不会在更改了。

存储内容一旦大于计划容量,若要存储更多内容,只能整体搬迁。即整个顺序表对象(指存储顺序表的结构信息的区域)改变了

 

示例:

计划8个容量,存储4个值

更改最后一个数据的内容d为e

因为存储数据变化,所以顺序表对象就变动了

 

分离式:

因为分离式,基本信息和存储元素是两个独立的对象,他们彼此间使用基本信息后面的逻辑地址来连接,所以存储数据变动,只不过是存储的逻辑地址变动,而存储对象中的基本信息没有发生变动,所以,对于顺序表对象来说,没有发生变动

示例:

计划8个容量,存储4个值

更改最后一个数据的内容d为e

通过上面对于两种顺序表结构的内容更新实践分析,数据发生变动,我们推荐使用分离式顺序表结构,为什么?因为对象没有变动,一体式相当于重新开辟了一片空间,产生了一个新的顺序表对象,没有分离式省事简便。

所以接下来分析数据内容增加的时候,我们只针对分离式顺序表结构。

 

空间扩容

采用分离式结构的顺序表,可以在不改变表对象的前提下,将数据存储区更换为存储空间更大的区域,所有使用这个顺序表的地方都不必修改。只要程序的运行环境(计算机系统)还有空闲存储,这种表结构就不会因为数据存储区空间不足满了而导致操作无法进行。人们把采用这种技术实现的顺序表称为动态顺序表,因为其容量可以在使用中动态变化。

目前动态顺序表的扩容策略分为两大类:线性增长、倍数增长

线性增长:

数据存储区容量一旦发现不足,每次扩充增加固定数目的存储区容量,如每次扩充增加4个元素位置。

特点:

确定性:因为增加数量有限制,所以节省空间,

不确定性:扩充操作可能频繁发生、随时发生。

倍数增长:

数据存储区容量一旦发现不足,每次扩充容量加倍,如:

当前容量8,容量不足时候,就扩充8,最终容量为16。

当前容量16,容量不足时候,就扩充16,最终容量为32。

...

如此循环往复,每次扩充的容量都是当前的容量空间大小。

特点:

确定性:每次增加容量会很大,所以扩充操作的执行次数不会频繁发生

不确定性:容量扩充答,可能会造成空间资源浪费。

根据上面对于动态顺序表的容量增加分析,可以知道,倍数增长方式是以空间换时间,因为目前空间代价越来越低廉,所以我们工作中推荐使用倍数增长的方式来调整容量空间。

 

隐含意思:单一元素的值就是顺序表  -- 后续所有知识点都会用到这一个认知

内容总结:

1、顺序表形式:基本布局(同类数据)+元素外置(异类数据)

2、顺序表结构:一体式+分离式(灵活)

3、顺序表容量扩充策略:线性(频繁)+倍增

4、顺序表元素增加:头[保序、O(n)]+尾[保序、O(1)]+位置[非保序、O(1)]

5、顺序表元素删除:头[保序、O(n)]+尾[保序、O(1)]+位置[非保序、O(1)]

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅谈数据结构与算法 的相关文章

随机推荐

  • 日常BUG:MOC‘ing 宏编译

    日常BUG MOC ing 宏编译 问题 qml中调用C 后台函数 该函数使用宏包围 如 ifdef MARCO Q INVOKABLE void xxx1 Q INVOKABLE void yyy2 endif 使用msbuild时 mo
  • Linux:C/Socket多路复用select

    版权声明 转载时请以超链接形式标明文章原始出处和作者信息及本声明 http kifzt blogbus com logs 4152790 html Linux C Socket多路复用select 小全 Submitted byELFero
  • Pie POJ - 3122【贪心、二分】

    该题连接 这是一道英文题 所以这里就不放原题了 我写一下它的题意 主人要开一个party 而主人有N个派 他要宴请F个人 也就是要有F 1个人要吃派 但这些人又很挑剔 他们每个人吃派只吃一种派 并且还不能容忍其他人吃的派比自己多 所以这就是
  • Calculate a + b and output the sum in standard format -- that is, the digits must be separated into

    题目描述 Calculate a b and output the sum in standard format that is the digits must be separated into groups of three by co
  • ssh免输入密码登录

    场景 服务器A 采用ssh 登录服务器B 没有任何特殊设置情况下 采用ssh host b 会出现提示Password 让输入密码 如何可以不手工输入密码 解决方案 生成ssh公钥和私钥 这里 t dsa表示采用dsa加密方式 回车后会让你
  • LINUX邮件收发

    1 一般邮件收发 启动服务 root kittod systemctl restart postfix 修改配置 vim etc postfix main cf 修改如下行 94 myhostname mail xixi com 102 m
  • nginx proxy_cache缓存详解

    目录 1 关于缓冲区指令 1 1 proxy buffer size 1 2 proxy buffering 1 3 proxy buffers 1 4 proxy busy buffers size 1 5 proxy max temp
  • Cause: java.sql.SQLException: Illegal mix of collations (utf8_german2_ci,IMPLICIT) and (utf8_general

    错误 Cause java sql SQLException Illegal mix of collations utf8 german2 ci IMPLICIT and utf8 general ci IMPLICIT for opera
  • Doraengineer‘s blog说明

    开设时间 2018年9月5日 个人介绍 本科系统工程专业 学习系统优化 系统仿真等技术 硕士控制科学与工程 方向计算机视觉 图像拼接 全景成像 目前从事数据方面工作 小白一枚 Github https github com 1993zlor
  • 本人常用资源整理(ing...)

    Deep Learning 深度学习 ufldl的2个教程 这个没得说 入门绝对的好教程 Ng的 逻辑清晰有练习 一 ufldl的2个教程 这个没得说 入门绝对的好教程 Ng的 逻辑清晰有练习 二 Bengio团队的deep learnin
  • 剑指offer:从尾到头打印链表(java版)

    描述 输入一个链表的头节点 按链表从尾到头的顺序返回每个节点的值 用数组返回 如输入 1 2 3 的链表如下图 返回一个数组为 3 2 1 0 lt 链表长度 lt 1000 示例1 输入 1 2 3 返回值 3 2 1 示例2 输入 67
  • Win11终于兼容安卓App!微软推送安卓子系统

    Win 11 正式版也已经推出 20 天了 不知道升级了的小伙伴用着怎么样 反正从正式版发布那天起 正式入手 Win 11 的我并没有碰到什么大的不妥 可以说从 Win 10 到 Win 11 的过渡整体感觉相当平稳 当然 UI 更新的吸引
  • 如何将数据库中存的树转化为树形列表(以easyui的tree为例)

    代码实现 Tree 类 public class Tree private String id private String text private String url private String state private Stri
  • RTP/RTCP协议解析

    RTP协议 实时传输协议RTP Real time Transport Protocol 是一个网络传输协议 它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的 后在RFC3550中进行更新 国际电信联盟ITU T也发布
  • python爬取12306实现按车次查询余票

    前言 本篇博客想写很久了 以前抢票时不知道你们有没有这种情况 比如你想买郑州到长春k926这个车次的票 但是车票买完了抢不到票 于是我就想多买几站看没有票 其实也贵不了多少 也就是说我想多买几站买这个车次郑州 gt 哈尔滨的票 然后到长春下
  • stm32 LWIP开发-1-LWIP 无操作系统移植

    1 网卡基础概念 1 开发板需要实现网络功能的话 需要两个条件 1 硬件 外置网络芯片或者MCU有网络功能 比如 stm32F1 DM9000 MAC PHY stm32F4 内置MAC层 PHY层芯片 2 支持TCP IP协议栈 2 st
  • 数字孪生技术与万亿市场规模的智慧城市

    数字孪生技术与万亿市场规模的智慧城市 近日 由工信部牵头编写的2020年 数字孪生应用白皮书 正式发布 重点介绍了数字孪生技术在智慧制造 智慧城市 智慧交通 智慧能源 智慧建筑 智慧健康6个领域的应用和发展 数字孪生技术在环保领域的应用 通
  • stm32设置延时函数

    查看网上设置延时函数的方法不外乎三种 统一总结一下 第一种 通过设置循环设置延时函数 通过时钟周期 机器周期 指令周期 来具体计算单片机执行一条指令的时间 来进行延时 这种延时不太精确 详细可以看看这篇文章https blog csdn n
  • Virtualbox虚拟机网络配置详解

    目录 1 使用桥接 Bridged Adapter 模式 2 使用HostOnly模式 网络共享的方式 3 使用双网卡 HostOnly模式 NAT转换 在默认情况下 Virtualbox虚拟机选择的上网方式是 网络地址转换 NAT 这种方
  • 浅谈数据结构与算法

    1 什么是数据结构 答 存储 组织数据的方式 数据的种类有很多 字符串 整数 浮点 组织各种数据的方式 即数据元素之间的关系 列表 字典 元组 举例 列表方式 老王 18 男 字典方式 name 老王 age 18 sex 男 综合方式 n