绪论
数据结构相关的概念
数据:是描述客观事物属性的数、字符及所有能输入到计算机中并能被计算机程序识别和处理的符号的集合。
数据元素:是数据的基本单元,可由多项数据项组成。
数据项:是构成数据元素的不可分割的最小单元。
数据对象:是具有相同性质的数据元素的集合,是数据的一个子集。
包含关系:数据项 数据元素 数据对象 数据
数据结构:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
在任何问题中,数据元素都不是孤立存在的,它们之间存在某种关系,这种数据元素相互之间的关系称为结构。
数据类型:是一个值的集合和定义在此集合上的一组操作的总称。
数据类型按照值是否可以再分,可分为原子类型和结构类型。
数据结构是数据的具体表现形式,是面向实现者的。
抽象数据类型,是数据的抽象表现形式,是面向使用者的。Pascal 语言定义的的数据类型可分为以下几类:
抽象数据类型(ADT):描述了数据的逻辑结构和抽象运算,通常用(数据对象,数据关系,基本操作集)这样的三元组来表示
ADT 是数据类型的数学模型,而与它在计算机中的表示与具体实现无关。可用 ADT 定义一个完整的数据结构:
通俗来说,抽象数据类型,泛指除基本数据类型以外的数据类型。使用抽象数据类型的好处是对基本数据类型进行封装,当作新的数据类型来使用,这样的话一次只需要操作一个数据类型,而不是多个数据类型。如 C 语言中用结构体来实现 ADT,C++ 和 Java 中用类来实现 ADT。
要清晰认知到,抽象数据类型也只是一种数据类型:
- 与存放数据的机器无关。
- 与跟数据存储的物理结构无关。
- 与实现操作的算法和编程语言皆无关。
数据类型的三要素
数据结构包括三方面的内容:逻辑结构、存储结构和数据的运算,缺一不可。
逻辑结构:是指数据元素之间的逻辑关系,即从逻辑关系上描述数据。
逻辑结构与数据的存储无关,是独立于计算机的。
逻辑结构的分类:
- 常用的线型结构有:线性表,栈,队列,双队列,数组,串;
- 常见的非线性结构有:二维数组,多维数组,广义表,数(二叉树等),图。
Tips:
- 集合,强调同类;线性结构,强调一对一;树形结构,强调一对多;图状结构或网状结构,强调多对多。
- 线性和树状存储结构用得比较多一点。
Tips:
- 我们说的具体数据结构,如顺序表、哈希表、单链表,既包含数据的存储结构,又包含数据的运算,所以不属于逻辑结构,我们可以称之为完整的数据结构。
- 逻辑结构只能从逻辑上来描述数据,如线性表、有序表。
- 有序表是指关键字有序的线性表,可以链式存储(单链表)也可以顺序存储(数组),没有要求数据的存储方式,仅描述了元素之间的逻辑关系,故它属于逻辑结构。
- 数据的逻辑结构是以面向实际问题的角度出发的,只采用抽象表达方式,独立于存储结构。
- 数据的逻辑结构,可以采用多种存储结构来实现。如满二叉树,既可以用顺序存储方式存储,亦可以用链式存储方式存储。
存储结构:是指数据结构在计算机中的表示(又称映像),也称物理结构。
Tips:
- 它包括数据元素的表示和关系的表示。
- 数据的存储结构是使用计算机语言实现的逻辑结构,它依赖于计算机语言。
数据的存储结构主要有顺序存储、链式存储、索引存储和散列存储:
- 顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。
(1) 其优点是可以实现随机存取,每个元素占用最少的存储空间;
(2) 缺点是只能使用相邻的一整块存储单位,因此可能产生较多的外部碎片。- 链式存储。不要求逻辑上相邻的元素在物理位置上也相邻,借助指示元素存储地址的指针来表示元素之间的逻辑关系。
(1) 其优点是不会出现碎片现象,能充分利用所有存储单位;
(2) 缺点是每个元素因存储指针而占用额外的存储空间,且只能实现顺序存取。- 索引存储。在存储元素信息的同时,还建立附加的索引表。索引表中的每项称为索引项,索引项的一般形式是(关键字,地址)。
(1) 其优点是检索速度快;
(2) 缺点是附加的索引表额外占用存储空间。另外,增加和删除数据时也要修改索引表,因而会花费较多的时间。- 散列存储。根据元素的关键字直接计算书该元素的存储地址,又称哈希(Hash)存储。
(1) 其优点是检索、增加和删除结点的操作都很快;
(2) 缺点是若散列函数不好,则可能出现元素存储单元的冲突,而解决冲突会增加时间和空间开销。Tips:
- 数据的存储结构是逻辑结构在计算机上的映射,它不能独立与逻辑结构而存在。
- 用得比较多的是顺序存储和链式存储,而后两种存储结构用的较少,但其各对应的一种数据类型,是两个考点。
- 链式存储设计时,各个不同节点的存储空间可以不连续,但是结点内的存储单元地址必须连续。
- 顺序存储特点简记为:存储单位相邻、随机存取、存储密度大。
数据的运算:施加在数据上的运算包括运算的定义和实现。运算的定义是针对逻辑结构的,指出运算的功能;运算的实现是针对存储结构的,指出运算的具体操作步骤。
综合题01 对于两种不同的数据结构,逻辑结构或物理结构一定不相同吗?
数据结构三要素:逻辑结构、存储结构、数据运算。
因此,两种不同的数据结构,逻辑结构与物理结构可以相同(正常情况下);
也可以不同(数据运算不同,逻辑结构与物理结构不同也被称为两种数据结构)。
例如,二叉树与二叉排序树是两种不同的数据结构。
二者均可以使用二叉树的逻辑结构与物理结构。
但是建立树、插入节点、删除节点和查找结点等数据运算是不同的。
因此,对于两种不同的数据结构,逻辑结构或物理结构不一定相同。综合题02 试举一例,说明对于相同的逻辑结构,同一种运算在不同的存储方式下实现,其运算效率不同。
线性表既可以用顺序存储方式实现,也可以用链式存储方式实现。
在顺序存储方式下,在线性表中插入和删除元素,平均要移动近一半的元素,时间复杂度为 。
在链式存储方式下,插入和删除的时间复杂度都是 。