01数据结构概述
author:陈镇坤27
创建时间:2022年1月4日
文章目录
——————————————————————————————
一、基本概念和术语
核心:数据的逻辑结构、物理结构和操作集合
基本概念
数据是信息载体。
数据元素是数据基本单位,是一个个数据独立个体。例如学生
数据项,数据元素的组成部分。例如学分
数据对象,相同特征数据元素的集合,是多个数据独立个体的组成。例如学生数组。
数据结构,数据及数据元素的组织形式。要素为:数据对象、数据对象的元素之间的关系。四种基本数据结构形式:集合(电器集合)、线性(节气)、树形(院系组织)、图形或网状(选课系统涂装接结构)
数据类型,具有相同性质的操作对象及其运算方法的集合。
数据类型约等于简单的数据结构;取值范围为数据元素的有限集合
逻辑结构
数据逻辑结构,从具体问题抽象出的数学模型(线性结构、非线性结构)
逻辑结构数学表达式:B=(D,R),D:数据元素集合。R:数据元素之间前驱后继关系
表达式符号:<>有次序关系、()无次序关系。
例:
线性结构
D1={春,夏,秋,冬},R1={<春,夏>,<夏,秋>,<秋,冬>} 春无前驱,冬无后继
树型结构(每个层级部门的职位的直接领导只有一个)
D2={总经理,部门经理A,部门经理B,组长A,组长B,组长C,组长D,职工A,职工B,职工C,职工D,职工E,职工F,职工G}
R2={<总经理, 部门经理A>,<总经理, 部门经理B>,<部门经理A, 组长A>,<部门经理A, 组长B>,<部门经理B, 组长C>,<部门经理B, 组长D>,<组长A,职工A>,<组长A,职工B>,<组长A,职工C>, <组长D,职工D>,<组长D,职工E>,<组长D,职工F>,<组长D,职工G>}
图形结构(同一个人也可以是多个人共同的朋友)
D3={A某,B某,C某,D某,E某,F某,G某,H某}
R3={<A某,B某>,<A某,C某>,<B某,D某>,<B某,,E某>,<B某,F某>,<C某,F某>,<C某,G某>,<E某,H某>,<F某,H某>};
物理结构
顺序存储
衍生索引存储(索引文件表,分拆顺序表,提高查询效率)和散列存储(元素映射地址,尽量一对一)
数据元素在存储器中的相对位置可以体现数据元素在有序表中的前驱和后继关系
链式存储
元素除了需要存储自身数据外,还要存储与自身相关的其他数据的信息(一般是位置)
面向对象的数据结构表示
面向对象基础
类的声明与实例化
Java语言面向对象设计,而类与对象则是其核心。
在Java中,自定义一个类的实质是自定义一种数据类型
因此,必须将类实例化之后才能引用类中的成员变量和成员方法。
“实例化”就是使用类声明一个变量并通过new操作符以及构造器完成各成员变量的初始化 (这句话很精辟)
类的成员定义
类是数据及数据操作的封装体,我们所说的类成员,指的就是类的数据(成员变量)及数据的操作(成员方法)。
Java是完全面向对象的,方法不能独立存在,所有的方法都必须定义在类之中(大简隐于市,一直没注意到这一点)
抽象类
表达抽象概念的类,其运算处理皆为抽象,不能实现方法体。
抽象类及成员方法都必须用abstract来修饰以表明“抽象”身份。作为抽象概念的类,其无法被实例化,但可以被子类继承,子类必须实现抽象父类的成员方法。
泛型类
泛型就是一种包含了要运算处理的数据的类型尚不明确而临时使用类型参数(如K)来表示的一种自定义数据类型
泛型类在使用时必须明确指定各类型参数对应的实际数据类型,Java编译器在编译代码时将根据所指定的实际数据类型自动替换对应的类型参数
在自定义泛型时,可通过实例化Object对象,再强制转化为临时参数对应的类型数据方式泛型类进行操作(初始化、数据的增删改查等)。
面向对象的抽象数据类型
数据结构研究的是数据元素之间的逻辑关系,对数据的具体类型并不关心。
结构本身就是一种抽象概念。
数据对象、数据关系、数据间的基本操作组成一个完整的数据结构抽象模型。
通常表示为{D,S,P}
例子:
Java面向对象思想的抽象性与数据结构中的抽象数据类型的抽象性在目标上是相同的
因此数据结构的抽象数据类型可以通过Java的抽象类、泛型类或接口等进行表示。
Java提供了多种数据结构,包括ArrayList、Hashtable、LinkedList、Map、Queue、Set、Stack、TreeSet、Vector等
算法和算法分析
算法具有的基本特性:有穷、确定、可行、输入、输出、
算法效率的度量标准:正确性、可读性、健壮性、运行时间、占用空间
算法效率分析
算法执行的时间代价和空间代价是人们最关注的的两个点。
时间复杂度
因为硬件、环境等因素的不同,算法执行耗费时间在纵向上的比较不具备参考价值,而横向上的比较具有一般性。
通常认为,算法执行耗费时间与所处理问题规模大小相关,规模量用N表示
规模为n的算法执行时间(不是真实的耗费时间)被称为算法的时间复杂度。用T(n)表示(耗费时间T为n的函数)。
而为了横向的比较,一般将算法的基本操作的重复执行次数认为是其时间复杂度,表示为f(n)。
因此T(n) = f(n)。
由于精确计算算法的基本操作的频度依然十分困难,根据
一个算法的“运行工作量”通常随问题规模的增长而增长,因此比较不同算法的优劣主要应该以其“增长的趋势”为准则
我们采取的策略是
当n逐渐增大时T(n)的极限情况。一般把这种算法的渐进复杂度简称为时间复杂度(这是广义上的时间复杂度)
因此,时间复杂度常用数量级的形式来表示:T(n) = O(f(n))
O表示Order(翻译:数量级)。
这种数量级表示遵循下列规则:
当T(n)为多项式时,可只取其最高次幂,且其系数也可省略
至此,数量级的时间复杂度表示的不是基本操作的重复执行次数,而是估算的数量级。其着重体现的是随n增大,算法时间复杂度的变化趋势。
问:怎么找到一个问题中的基本操作语句?
答:找到随规模n扩大,语句执行次数变化最快的语句。
空间复杂度
算法空间复杂度由三部分因素组成:算法源代码占用的空间、输入输出数据占用的空间、算法运行过程中占用的临时空间。
表示为S(n)=O(f(n))。
问题中的基本操作语句?
答:找到随规模n扩大,语句执行次数变化最快的语句。
[外链图片转存中…(img-3UxYIUFP-1641479215929)]
空间复杂度
算法空间复杂度由三部分因素组成:算法源代码占用的空间、输入输出数据占用的空间、算法运行过程中占用的临时空间。
表示为S(n)=O(f(n))。