数据定义语言(Date Definition Language,简称DDL)负责数据的模式定义与数据的物理存取构建;数据操纵语言(Date Manipulation Language,简称DML)负责数据的操纵,包括增、删、改等操作。
线性表
线性表(Linear list)是最简单且最常用的一种数据结构。这种结构具有下列特点:存在一个唯一的没有前驱的(头)数据元素;存在一个唯一的没有后继的(尾)数据元素;此外,每一个数据元素均有一个直接前驱和一个直接后继数据元素。
线性表的概念及运算
线性表的逻辑结构
线性表是n个类型相同的数据元素的有限序列,数据元素之间是一对一的关系,即每个数据元素最多有一个直接前驱和一个直接后继,如图2.1所示。例如:英文字母表(A,B,…,Z)就是一个简单的线性表,表中的每一个英文字母是一个数据元素,每个元素之间存在唯一的顺序关系,如在英文字母表字母B的前面是字母A,而字母B的后面是字母C。在较为复杂的线性表中,数据元素(data elements)可由若干数据项组成,如学习成绩及平均成绩等数据项(item)组成,常被称为一个记录(record),含有大量记录的线性表称为文件(file)。数据对象(data object)是性质相同的数据元素集合。
如表2-1所示的车辆登记数据文件,每辆车的相关信息由车牌号、车、车型和颜色四个数据组成,它是文件的一条记录(数据元素)。
表2-1 车辆登记表 | |||
车牌号 | 车名 | 车型 | 颜色 |
A13850 | 奥迪 | 卧车 | 黑色 |
B49271 | 福田 | 小卡 | 白色 |
A66789 | 东风 | 大卡 | 绿色 |
… | … | … | … |
综上所述,将线性表定义如下:
线性表(Linear List)是由n(n≥0)个类型相同的数据元素a1,a2,…,an组成的有限序列,记作(a1,a2,…,ai-1,ai,ai+1,…,an)。这里的数据元素ai(1≤i≤n)只是一个抽象的符号,具体含义在不同情况下可以不同,它既可以是原子类型,也可以是结构类型,但同一线性表中的数据元素必修属于同一数据对象。此外,线性表中相邻数据元素之间存在着序偶关系,即对于非空的线性表(a1,a2,…,ai-1,ai,ai+1,…,an),表中ai-1领先于ai,称ai-1是ai的直接前驱,而称ai是ai-1的直接后继。除了第一个元素a1外,每个元素ai有且仅有一个被称为其直接前驱的结点ai-1,除了最后一个元素an外,每个元素ai有且仅有一个被称为直接后继的结点ai+1。线性表中元素的个数n被定义为线性表的长度,n=0是称为空表。
线性表的特点可概括如下:
统一性:线性表由同类数据元素组成,每一个ai必须属于同一数据对象。
有穷性:线性表由有限个数据元素组成,表长度就是表中数据元素的个数。
有序性:线性表中表中相邻数据元素之间存在着序偶关系<ai,ai+1>。
由此可看出,线性表是一种最简单的数据结构,因为数据元素之间是由一前驱一后继的直观有序的关系确定;线性表优势一种最常见的数据结构,因为矩阵、数组、字符串、对战、队列等都符合线性条件。
线性表的抽象数据类型定义
一个抽象数据类型定义了一个模型,但不涉及模型的具体实现问题。下面给出线性表的抽象数据类型定义。
ADT LinearList{
数据元素:D={ai|ai∈D0,i=1,2,…,n,n≥0,D0为某一数据对象}
关系:S={<ai,ai+1>|ai,ai+1∈D0,i=1,2,…,n-1}
基本操作:
(1) InitList(L)
操作前提:L为未初始化线性表。
操作结果:将L初始化为空表。
(2)DestroyList(L)
操作前提:线性表L已存在。
操作结果:将L销毁。
(3)ClearList(L)
操作前提:线性表L已存在。
操作结果:将表L置为空表。
(4)EmptyList(L)
操作前提:线性表L已存在。
操作结果:如果L为空表则返回真,否则返回假。
(5)ListLength(L)
操作前提:线性表L已存在。
操作结果:如果L为空表则返回0,否则返回表中的元素个数。
(6)Locate(L,e)
操作前提:表L已存在,e为合法元素值。
操作结果:如果L中存在e,则将“当前指针”指向元素e所在位置并返回真,否则返回假。
(7)GetDate(L,i)
操作前提:表L存在,且i值合法,即1≤i≤ListLength(L)。
操作结果:返回线性表L中第i个元素的值。
(8)InsList(L,i,e)
操作前提:表L已存在,e为合法元素值且1≤i≤ListLength(L)+1。
操作结果:在L中第i个位置插入新的数据元素e,L的长度加1。
(9)DelList(L,I,&e)
操作前提:表L已存在且非空,1≤i≤ListLength(L)。
操作结果删除L的第i个数据元素,并用e返回其值,L的长度减1。
}ADT LinearList
在实际问题中对线性表的运算可能很多,例如需要将两个或两个以上的线性表合并成一个线性表;把一个线性表分拆成两个或两个以上的线性表;进行多种条件的合并、分拆、复制、排序等运算。可利用基本运算的组合来实现符合运算。由于线性表应用的广泛性,线性表中的数据元素可能属多种类型,因此可以使用面向对象程序设计中的多型数据类型。
线性表的抽象数据类型定义中给出的各种操作是定义在线性表的逻辑结构上的,用户只需了解各种操作的功能,而无需知道它们的具体实现。各种操作的具体实现与线性表具体采用那种存储结构有关。
在计算机内存放线性表,主要有两种基本的存储结构:顺序存储结构和链式存储结构。此外还有一种叫做静态链表的存储结构,他是用顺序存储结构的存储方式模拟实现的一种链式存储结构。下面我首先学习采用顺序存储结构的现象表。
线性表的顺序存储
线性表的顺序存储结构
线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反应数据元素之间逻辑上的相邻关系。采用顺序存储结构的线性表通常称为顺序表。
假设线性表中有n个元素,每个元素占k个单元,第一个元素的地址为loc(a1),则可以通过如下公式计算出第i个元素的地址loc(ai):
Loc(ai)=loc(a1)+(i-1)×k
其中loc(a1)称为基地址。
图2.2给出了线性表的顺序存储结构示意图。从图中可看出,在顺序表中,每个结点ai的存储地址是该结点在表中的逻辑位置i的线性函数,只要知道线性表中的一个元素的存储地址(基地址)和表中每个元素所占存储单元的多少,就可以计算出线性表中任意一个数据元素的存储地址,从而实现对顺序表中数据元素的随机存取。
顺序存储结构可以借助于高级程序设计语言中的一堆数组来表示,一维数组来表示,一维数组的序号相对应。
线性表的顺序存储结构可用C语言定义如下:
要注意区分元素的序号和数组的下标,如a1的序号为1,而去对应的数组下标为0。
要将L定义为SeqList类型的变量,可用说明语句:SeqList L;如将L定义为指向DeqList类型的指针,则用说明语句:SeqList *L。
明天我将要学习线性表顺序存储结构上的基本运算