数据结构的基本概念
1. 基本概念以及术语
1.1 数据
数据:信息的载体,是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。例如在生活中,我们的身份信息、看到的图片、听到的音乐都可以作为数据来进行输入和处理。
数据对象:具有相同性质的数据元素的集合,是数据的一个子集。例如所有人的身份信息可以作为一个数据对象。
数据元素:数据的基本单位,通常作为一个整体进行考虑和处理。例如每一个人的身份信息可以就是一个数据元素。
数据项:构成数据元素的不可分割的最小单位。在身份信息中,有姓名、有身份编号,这样的 信息就是数据元素中的数据项。
例如,上图是具有人物和螃蟹的数据的集合。其中所有的人物就是一个数据对象,它是具有相同性质的数据元素的集合;每一个人物都是一个数据元素,可能在该人物当中,帽子的颜色、书包的颜色都可以作为数据项。
数据类型:是一组值的集合和定义在该集合上的操作的总和。其中有原子类型,原子就是不可再分割的意思,它是原子类型值的集合和定义在该集合上的操作。例如在C语言中的int、char、float等都是原子类型。除了原子类型,还有结构类型,它是结构的集合和定义在集合上的操作。结构就是多个原子类型值的组合,其中有list、map、set等。最后还有抽象数据类型,它是数据模型以及定义在该数据模型上的操作,可以用一个三元组来表示,分别是数据对象、数据关系和相关的操作。对于抽象数据类型,只考虑它的逻辑特性,具体的内部实现是不考虑的。例如在生活中所有的人、汽车都可以把它抽象出来作为一种抽象数据类型。
1.2 结构
姓名 | 班级 | 成绩 |
---|---|---|
小明 | 1 | 100 |
小红 | 2 | 99 |
小张 | 3 | 98 |
小兰 | 4 | 97 |
这是一张成绩单,如果把这张成绩单叫做一个数据对象的话,那么每一个人的姓名可以称作为一个数据项,而每一人所有的信息是一个数据元素。这张表还有类似小明排在小红前面这样的关系,这样的关系就是所说的结构。
结构:数据不是孤立存在的,它们存在着某种关系,这种相互的关系我们叫做结构。
这样就有了数据结构的一个概念。数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
2. 数据结构的三要素
数据结构有三个要素:逻辑结构、物理结构、数据的运算
2.1 逻辑结构
逻辑结构是指数据元素之间的逻辑关系,它更贴近现实,即从逻辑关系上来描述数据。它是独立于计算机的,与计算机内部如何存储是无关的。
在逻辑结构中,具体分为四种:线性结构、集合、树形结构、图状结构。其中,把集合、树形结构、图状结构统称为非线性结构。
2.1.1 线性结构
在生活中有许多线性结构的例子,比如排队买票时,排的队伍就是一个线性结构。在对成绩进行从小到大排序,它也是一个线性的结构。
2.1.2 集合
集合是指除了所有的元素均在一个集合之内,之外再无其他的关系。在数学中,所有整数就是一个集合,所有的小数也是一个集合。
2.1.3 树形结构
树形结构是指一对多的关系。比如说狗是一类的总称,狗中又有柯基、哈士奇等具体的种类,这样一个种类的分支关系,它们就是一个树形结构。
2.1.4 图状结构
图状结构也叫做网状结构,它是多对多的关系。比如城市的交通网络,每一个城市都连接着其他的许多城市。
2.2 存储结构
存储结构是指数据结构在计算机内的表示,也称为物理结构。它既包括数据元素本身的表示,也包括数据元素之间关系的表示。
存储结构也分为四种:顺序存储、链式存储、索引存储、散列存储。
2.2.1 顺序存储
数据在内存当中,会把它存放在一个一个的存储单元之中,而顺序存储的意思是值在逻辑上相邻的元素在物理存储上也让它相邻。
例如,a、b、c、d、e五个元素在逻辑上是相邻的,那么把它存放到存储单元之中也让它们相邻。
顺序存储元素之间的关系是通过物理位置的相邻来体现的,其最大的好处就是可以实现随机存储,在知道第一个单位的位置时,通过简单的运算,根据它相邻的特性也就知道其后所有元素的数据位置
2.2.2 链式存储
链式存储是指在逻辑上相邻的元素,在物理存储位置上是不相邻的。链式结构通过名字来看,它有一个链接的含义,它在具体的实现上也是利用这样一个具体操作的。
存放数据元素a的位置的同时后面也存放了下一个元素的地址,通过这个地址来体现元素之间的关系达到一个指针的效果。
在链式存储当中,每一个数据元素存放的物理单位位置是不确定的,它们的距离可能很远也可能很近,无法通过在顺序存储那样的手段来找到下一个元素的位置。但是在链式存储中,是通过指针来表示相邻元素的关系的。所以在存取手段上,要通过指针来找到下一元素的位置。所以在链式存储中只能实现顺序存储而无法实现随机存储。
例如在图 1-4 中 a、b、c 三个元素在逻辑上是相连的,假设它是顺序存取的,那么想要找到 c 这个元素,就可以通过锁定 addr2 找到了,因为它在逻辑单元上是连续存放的。而在图 1-5 中,首先通过存放 a 元素的存储单元知道下一个存储单元的地址是 addr7 ,找到了 b 的位置之后,再通过 b 存储单元中 c 的指针,也就是 addr9 找到了 c,只有这样以此的查找才能找到 c 的位置。
2.2.3 索引存储
索引存储在内存中不仅仅要存放每一个数据元素,还要建立一张索引表。在索引表中有一个个索引项,每一个索引项都存放两个信息,一个是关键字,另一个是该关键字查找数据对应的地址。
例如,想要锁定 c 在存储单元中的位置,通过关键字 n 找到了 c 对应的存储单元地址是 addr8 。通过这样一个个索引项可以非常快速的找到对应存储数据的地址。
但是,索引存储有一个缺点,就是既要存放数据元素,又要存放索引表,在存放索引表的时候会消耗内存资源。
2.2.4 散列存储
散列存储也称为哈希存储,它是通过关键字的相应函数运算直接求得对应数据元素的地址
例如,通过 f(n) 的这个函数运算直接求得数据元素 c 的存放地址 addr8 。它的查找速度也是非常快的。
2.3 数据的运算
数据的运算包括运算的定义和实现方式,运算的定义针对逻辑结构,运算的实现针对存储结构。
例如:现在有这样一个简单的逻辑结构,其中 C 是 A 的后继节点,B 是 C 的后继节点,为了理解对应关系,设计了这样一个存储结构,数据元素 A 存放在了地址单元当中的 addr0 ,数据元素 B 存放在了 addr1 ,数据元素 C 存放在了 addr2 。现在要实现的运算是找到 A 的下一个节点。可以发现,在这个例子中,A 的下一个节点是有所不同的
根据上述的概念,运算的定义针对逻辑结构,找到的 A 的下一个节点是 C,运算的实现针对存储结构,找到的 A 的下一个节点是 B,所以说不同的结构,数据的运算也是不同的。
3. 总结
重点:数据结构的三要素