1.1.1 数据结构的定义:
- 数据(data):描述客观事物的数和字符的集合
- 数据项(data item):具有对含义的数据最小单位,也称为字段或域
- 数据对象(data object):是指性质相同的数据元素的集合,它是数据的一个子集
- 数据结构(data structure):是指所有数据元素以及数据元素之间的关系,可以看作是相互存在着某种特定关系的数据元素的集合
数据结构通常包括以下两个方面:
- 数据的逻辑结构:由数据元素之间的逻辑关系构成
- 数据的存储结构:数据元素及其关系在计算机存储器中的存储表示,也称为数据的物理结构
- 数据的运算(operation):施加在该数据上的操作
1.1.2 逻辑结构
数据的逻辑结构是从数据元素的逻辑关系上描述数据的,实际数据元素之间的逻辑关系的整体,通常是从求解问题中提炼出来的
- 逻辑结构的表示:
- 图标表示
- 二元组表示:B = (D,R) 数据结构B,由数据元素集合D以及D上的二元关系的集合R所组成
- 逻辑结构的类型:
- 集合:R为空集
- 线性结构:除了开始元素和终端元素之外,其余元素都有且只有一个前驱元素,有且只有一个后继元素.线性表就是一种典型线性结构
- 树形结构:除了开始元素以外,每个元素有且只有一个前驱元素,除了终端元素之外,每个元素有一个或多个后继元素.二叉树就是一种典型的树形结构.
- 图形结构:数据元素之间存在多对多的关系,每个元素的前驱元素和后继元素的个数可以是任意的,因此图形结构可能没有开始元素和终端元素,也可能有多个开始元素,多个终端元素.
1.1.3 存储结构
数据逻辑结构在计算存储器中的存储表示成为数据的存储结构(也称为映像),也就是逻辑结构在计算机中的存储实现.
- 顺序存储结构:采用一组连续的存储单元存放所有的数据元素,占有一整块存储空间,主要优点:存储效率高,可以实现对元素的随机访问.主要缺点:不便于修改数据,对元素的插入和删除操作可能需要移动一系列的元素
例如:
struct{
int number;
char name[8];
char sex[2];
char class[4];
}Student[10] = {{1,"李想","男","9901},...};`
- 链式结构存储:每个逻辑元素用一个内存结点存储,每个结点是单独分配的,所有的结点地址不一定是连续的,所以无须占用一整块存储空间.主要优点:便于数据修改,在对元素进行插入或删除操作时仅需要改相应的结点指针域,不必移动结点.主要缺点:存储空间的利用率低,逻辑上相邻的元素在存储空间中不一定相邻,所以不能对元素进行随机存取.
例如:
typedef struct Studnode{
int number;
char name[8];
char sex[2];
char class[4];
struct Studnode * next;
}Studtype;
- 索引存储结构:在存储数据元素的同时还建立了附加的索引表.存储所有数据元素信息的表称为主元素表,其中每个数据元素有一个关键字和对应的存储地址.优点:查找效率高.缺点:需要建立索引表,增大了空间开销.
- 哈希存储结构:基本思想是根据元素的关键字通过哈希函数直接计算一个值,并将这个值作为该元素的存储地址.这种结构能够进行快速查找和插入场合.
1.1.4 数据运算
具体如下表
1.1.5.1 数据类型
1 .数据类型
- c/c++语言中常用的数据类型
- c/c++语言中指针类型
- c/c++语言中数组类型
- c/c++语言中结构体类型
- c/c++语言中共用体类型
- c/c++语言中自定义类型:例如
typedef struct Student
{
int number;
char name[8];
char sex;
int classnumber;
}Newtype;
Newtype s1,s2;
2 .存储空间的分配
- 静态存储空间分配方式:是在程序编译期间分配固定的存储空间的方式,该存储分配方式通常是在变量定义时就分配存储单元并一直保持不变,直至整个程序结束,如定义数组
- 动态存储空间分配方式:是在程序运行期间根据需要动态地分配存储空间,在c/c++提供相应机制用于动态存储分配,如malloc()/free()
1.1.5.2 抽象数据类型
抽象数据类型ADT(abstract data type)是指用户进行软件系统设计时从问题的数学模型中抽象出来的逻辑数据结构和逻辑数据结构上的运算,而不考虑计算机的具体存储结构和运算的具体实现算法.例如定义复数类Complex.
1.2 算法及其描述
1.2.1 什么是算法
算法是对特定问题求解步骤的一种描述,它是指令有限序列.
一个算法应该具有以下五个重要的特性:
- 有穷性:任何不会终止的算法都是没有意义的
- 确定性:对于相同的输入,只能得出相同的输出
- 可行性:算法可以通过有限基本操作完成,也就是说算法中每个动作能够被机械的执行
- 有输入:一个算法有零个或者个输入
- 有输出:一个算法有一个或者多个输出
1.2.2 算法设计的目标
算法设计正确应该满足以下几个目标:
- 正确性:算法能够正确地执行预先规定的功能和性能要求
- 可使用性:要求算法能够很方便地使用,这个性质也叫用户友好性
- 可读性:算法应该易于使人理解,可读性好
- 健壮性:要求算法有很好的容错性,即提供异常处理,能够对不合理的数据进行检查,不经常出现异常中断或者死机现象
- 高效率和低存储量需求:通常算法的效率主要指算法的执行时间,执行时间最短则效率更高.
1.2.3 算法描述
一个算法通常完成某个单一的功能,算法设计的一般步骤如下:
- 分析算法的功能
- 确定算法有哪些输入,将这些输入设计成输入型参数,确定算法有哪些输出,将这些设计成输出型参数
- 设计函数体,完成从输入到输出的过程.
1.3 算法分析
1.3.1算法分析概述
- 算法分析就是分析算法占用计算机资源的多少,计算机的主要资源是CPU时间和内存空间
- 算法分析目的是分析算法的时空性能以便改进算法
1.3.2 算法时间性能分析
1 . 两种算法时间性能的分析方法:事后统计法,事前分析法(我们主要使用的分析手段)
2 .算法时间复杂度分析
- 计算算法的频度T(n),即计算算法的原操作和输入规模之间的关系(原操作是指:赋值,I/O和一些计算语句)
- T(n) 用O表示 T(n) = O(f(n)) 其含义是为T(n)找到一个上界f(n) 所以算法的时间复杂度也称为渐进时间复杂度,他表示随问题规模n的增大,算法执行时间的增长率和f(n)函数的增长率相同 一般情况下 若程序中无与输入规模n相关的的原操作,记作O(1),也称常数阶 我们将O(n)称为线性阶,O(n2)称为平方阶,O(log2n)称为对数阶,O(2n)称为指数阶 此外O(log2n),O(n),O(nlog2n),O(n2)称为多项式时间复杂度,将O(2n),O(n!)称为指数时间复杂度,一个问题目前可以用多项式时间复杂度的算法来求解称为P问题,一个问题目前只能用指数时间复杂度来求解,称为NP问题,NP = P 即求解NP问题的指数时间复杂度能否转换为多项式时间复杂度算法俩求解,是目前计算机科学的难题之一.
- 时间复杂度的求和,求积定理 求和定理:T1(n) = O(f(n)) T2(n) = O(g(n)),那么先执行p1,后执行p2的总执行时间是T1(n)+T2(n) = O(max(f(n),g(n))) 求积定理:T1(n)*T2(n) = O(f(n)*g(n))
3 算法的最好,最坏和平均时间复杂度
设一个算法的输入规模为n,Dn 是所有输入(实例)的集合,任意输入I∈Dn,P(I)是I出现的频率,有∑(I∈Dn)P(I) = 1,T(I)是算法在输入下所有执行的基本操作的次数,则该算法的平均时间复杂度是E(n) = ∑(I∈Dn)P(I)*T(I) [就是关于所有可能输入和执行时间的数学期望]
4 递归算法时间复杂度分析
写出递推表达式然后计算原操作执行的次数 并求和
1.3.3 算法空间性能分析
1 算法空间复杂度分析
算法空间复杂度是对一个算法在运行过程临时占用的存储空间大小的量度.
给出表达式 S(n) = O(g(n))
2递归算法空间复杂度分析
与上面的递归时间复杂度类似.
1.4 数据结构 + 算法 = 程序