数据结构是介于数学、计算机硬件和计算机软件三者之间的一门核心课程,数据结构不仅是一般程序设计(特别是非数值计算的程序设计)的基础,而且是设计和实现编译程序、操作系统数据库系统及其它系统程序和大型应用程序的重要基础。
数据(data): 是对客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。计算机输入和处理的数据除数值外,还有字符串、表格、图像甚至声音等,它们都是数字编码范畴。
数据元素(data element) :数据的基本单位,在计算机程序中通常作为一个整体,一个数据元素可以由若千个数据项组成,也可以只由一个体进行考虑和处理。数据项组成。数据元素又被称为元素、结点(node)或记录(record)。
数据项(data item): 指数据的不可分割的、含有独立意义的最小单位,数据项有时也称字段(field)或域。(如表中的列)
数据对象(Data object) : 是性质相同的数据元素的集合,是数据的一个子集。如Boolean={false,true}, Digit={0,1,2,3,4,5}。它们都是数据对象,是一组实例或值。数据对象的实例要么是一个原语(primitive或atomic),要么是由其他数据对象的实例组合而成。对后一种情况我们称对象实例的单个组件为元素(element)。
抽象数据类型(Abstract Data Type 简称ADT): 表示(类C语言表示)
ADT抽象数据类型名[
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}
1、定义
指一系列确定的而且是在有限步骤内完成的操作。特点如下:
- 有穷性:能执行结束
- 确定性:对于相同的输入执行相同的路径
- 0至多个输入
- 1多个输出
- 有效性(可行性)(用于描述算法的操作都是足够基本的)
2、算法与数据结构的关系
计算机科学家沃斯(N.Wirth)提出的:”“程序 =数据结构 + 算法“
,一个算法总是建立在一定数据结构上的;反之,算法不确定,就无法决定如何构造数据。
3、算法设计的要求
- 正确性:四层含义: (1)无语法错误; (2) 一般输入得出满足规格说明要求的结果; (3)边界、苛刻数据能产生满足规格说明要求的结果, (4)一切合法输入都能产生满足规格说明要求的结果。
- 可读性:首先是给人读,然后才是机器执行
- 健壮性:容错性
- 效率与低存储量需求
4、算法的效率:
一个算法如果能在所要求的·
资源限制
内将问题解决好,则称这个算法是有效率的。.例如,一个资源限制是:可用来存储数据的全部空间一-可能是分离的内存空间限制和磁盘空间限制以及允许执行每一个子任务所需要的时间。
5、算法的性能的评价:
- 算法所需的计算时间
- 算法所需的存储空间
- 算法的简单性
衡量算法的标准有时间和空间两个维度,具体到评价标准为时间复杂度和空间复杂度
1、算法的时间复杂度
定义:一般情况下,算法中基本操作重复执行的时间是问题规模n的某个函数f(n),算法的时间量度记作
T(n) = O(f(n)) “大O记法
它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度
2、复杂度的描述
由于算法的时间复杂度分析只考虑相对于问题规模n的增长率,因而,在难以精确计算基本操作执行次数的情况下,只要求出它关于n的增长率即可。
我们可以在计算任何算法运行时间代价时,忽略所有的常数和低次项:
常量阶: 时间复杂度为O(1)
线性阶: 时间复杂度为O(n)
平方阶: 时间复杂度为O(n2)
对数阶: O(log2n)
指数阶: O(2n)
例:如果某算法的运行时间代价为O(5n2 + n),可以忽略其中的低次项和常数,而视该算法的时间复杂度为O(n2)。
3、时间复杂度的等级
以下六种计算算法时间的多项式是最常用的。其关系为:Gamma公式展示
O ( 1 ) < O ( l o g n ) < O ( n ) < O ( n l o g n ) < O ( n 2 ) < O ( n 3 ) O(1)
指数时间的关系为: O ( 2 n ) < O ( n ! ) < O ( n n ) \ O(2^n)
数据结构(Data Structure):是相互之间存在一种或多种特定关系的数据元素的集合。
数据结构包括逻辑结构和物理结构两个层次。
- 逻辑结构是面向问题的:
- 物理结构是面向计算机的
1)数据的逻辑结构
数据元素之间存在的一种或多种特定的关系被称为数据的逻辑结构。通常有四类基本结构:集合、线性结构、树形结构、图状结构
2)数据的物理结构
物理结构,又称存储结构。数据的存储结构是逻辑结构在计算机存储器中的实现。数据元素在计算机中主要有两种不同的存储方法: 顺序存储结构和链式存储结构
线性表(Linear List),线性表(Linear List)是n(n20)个数据元素的有限序列,表中各个数据元素具有相同的特性,既属于同一数据对象,表中相邻的数据元素之间存在“序偶”关系。是最简单,也是最基本的一种线性数据结构
通常将线性表记做
( a 1 , a 2 . . . , a i − 1 , a i , a i + 1 , . . . , a n − 1 , a n ) \ (a_1, a_2 ..., a_{i-1} ,a_i, a_{i+1}, ..., a_{n-1}, a_n ) (a1,a2...,ai−1,ai,ai+1,...,an−1,an)
表中 a i − 1 \ a_{i-1} ai−1领先于 a i \ a_i ai, a i \ a_i ai领先于 a i + 1 \ a_{i+1} ai+1,称 a i − 1 \ a_{i-1} ai−1是 a i \ a_i ai的直接前驱元素, a i + 1 \ a_{i+1} ai+1是 a i \ a_i ai的直接后继元素n是表的长度。
当n=0时,表为空。a是第一个数据元素,a是最后一个数据元素,a;是第i个数据元素其中i为数据元素a在线性表中的位序
除了这种优先关系之外,在线性表中不再有其他的结构
例1:简单的线性表
例2:复杂点的线性表如下,每一行的数据为一个数据元素
线性表的存储结构:
ADT List{
数据对象:D={ai |ai ∈ ElemSet,i=1,2,...,n,n>0}
数据关系:R1={<ai-1,ai lai-1,aieD,i=2,...n}
基本操作:
1) lnitList (&L): 操作结果:将L初始化为空表
2) DestroyList(&L) : 操作前提:线性表L已存在。操作结果:将L销毁
3) ClearList(&L): 操作前提:线性表L已存在。操作结果:将表L置为空表。
4) EmptyList (L): 操作前提:线性表L已存在.操作结果: 如果L为空表则返回真,否则返回假
5) ListLength (L): 操作前提:线性表L已存在。操作结果: 如果L为空表则返回0,否则返回表中的元素个数
6) Getltem(L,i,&e): 操作前提: 表L已存在,1<=i<=listlength(L)。操作结果: 用e返回L中第i个元素的值。
7) LocateElem(L,e):操作前提: 表L已存在,e为合法元素值。操作结果: 如果L中存在元素e,则将“当前指针”指向元素e所在位置并返回真,否则返回假
8)ListInsert(&Lie):操作前提: 表L已存在,e为合法元素值且1<i<ListLength(L)+1。操作结果: 在L中第i个位置之前插入新的数据元素e,L的长度加1.
9)PriorElem( L,cur e, &pre e):如果cur e是L中的元素,并且不是第一个,则用pre e返回它的前驱。否则失败。
10) NextElem( L,cur e,&next e):如果cur e是L中的元素,并且不是最后一个,则用next e返回它的后继。否则失败。
11)ListDelete(&L,i,&e):操作前提: 表L已存在且非空,1<iListLength(L)。操作结果: 删除L的第i个数据元素,并用e返回其值,L的长度减1
}ADT List
栈和队列是两种重要的线性结构。从数据结构的角度看,栈和队列是操作受限的线性表:
栈:限定只能在表的一端进行插入和删除的特殊的线性表
后进先出
(Last In First Out),简称为LIFO线性表常用操作:初始化栈InitStack(S)、入栈 Push(&S,e)、 出栈 Pop(&S,&e)、获取栈顶元素内容 、GetTop(S,&e)、判断栈是否为空StackEmpty(S)
队列(queue)是一种先进先出(FIFO)的线性表,它只允许在表的一端–称为队尾(rear)进行插入操作,而在另一端一称为队头(front)进行删除操作。如图所示
队列(queue)的场景:: 排队取款、排队购物、排队上车、排队打饭等;WEB客户端的请求在服务器端的排队。
串是由零个或多个字符组成的有限序列,记作: S = ′ c 1 c 2 c 3 . . . c n ′ \ S='c_1c_2c_3...c_n' S=′c1c2c3...cn′
其中,S是串名字c1c2c3…cn’是串值,ci是串中字符,n是串的长度,表示串中字符的数目
空串:零个字符的串称为空串
子串:串中任意个连续的字符组成的子序列
主串:包含子串的串
空串是任意串的子串,任一串是它自身的子串。除它本身外一个串的其它子串都是它的真子串
例:假设a、b、c、d为如下4个串:a=BEl’ b=’JING‘ c=BEIJING d=BEIJING
a,b是C的子串,也是d的子串,但c不是d的子串