绪论
理论
数据结构
- 例如海底捞的排号
- 数据结构:某个特定门店的排队顾客信息和它们之间的关系
数据对象:全国所有门店的排队顾客信息
- 数据结构
- 逻辑结构
- 存储结构(以线性结构为例)
- 若采用顺序存储,则各个数据元素在物理上必须是连续的;若采用非顺序存储,则各个数据元素在物理上可以是离散的
- 数据的存储结构会影响存储空间分配的方便程度。
- 数据的存储结构会影响对数据运算的速度。
确定一种存储结构,就意味着在计算机中表示出数据的逻辑结构。存储结构不同,也会导致运算的具体实现不同。确定了存储结构,才能实现数据结构。
算法
时间复杂度
- 顺序执行的代码只会影响常数项,可以忽略。
- 只需挑循环中的一个基本操作分析它的执行次数与n的关系即可。
- 如果有多层嵌套循环,只需关注最深层循环循环了几次。
空间复杂度
- 无论问题规模怎么变,算法运行所需的内存空间都是固定的常量,算法空间复杂度为S(n)=O(1)。
算法原地工作——算法所需内存空间为常量。- 只需关注存储空间大小与问题规模相关的变量。
- 空间复杂度=递归调用的深度。
严蔚敏版数据结构附加笔记
补充理论
- 抽象数据类型可用三元组表示(D,S,P)
其中,D是数据对象,S是D上的关系集,P是对D的基本操作集。- Status是函数的类型,其值是函数结果状态代码。
书本代码
三元组
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef ElemType *Triplet;
1. 初始化三元组
//构造三元组T,依次置T的3个元素的初值为v1,v2,v3.
//操作结果:构造了三元组T,元素e1,e2,e3分别被赋以参数v1,v2,v3的值。
Status InitTriplet(Triplet &T, ElemType v1, ElemType v2, ElemType v3){
T = (ElemType *) malloc(3 *sizeof (ElemType));
if(!T)
exit(OVERFLOW);
T[0] = v1;
T[1] = v2;
T[2] = v3;
return OK;
}
2. 销毁三元组
Status DestroyTriplet(Triplet &T){
free(T);
T = NULL;
return OK;
}
3. 用e返回T的第i元的值
Status Get(Triplet T, int i, ElemType &e){
//初始条件
if(i < 1 || i > 3)
return ERROR;
e = T[i-1];
return OK;
}
4. 改变T的第i元的值为e
Status Put(Triplet &T, int i, ElemType e){
if(i < 1 || i > 3)
return ERROR;
T[i-1] = e;
return OK;
}
5. 如果T的3个元素按升序排列,则返回1,否则返回0
Status IsAscending(Triplet T){
return (T[0] <= T[1])&&(T[1] <= T[2]);
}
6. 如果T的3个元素按降序排列,则返回1,否则返回0
Status IsDescending(Triplet T){
return (T[0] >= T[1])&&(T[1] >= T[2]);
}
7. 用e返回T的3个元素中的最大值
Status Max(Triplet T, ElemType &e){
e = (T[0] >= T[1]) ? ((T[0] >= T[2]) ? T[0] : T[2]) : ((T[1] >= T[2]) ? T[1] : T[2]);
return OK;
}
8. 用e返回T的3个元素中的最小值
Status Min(Triplet T, ElemType &e){
e = (T[0] <= T[1]) ? ((T[0] <= T[2]) ? T[0] : T[2]) : ((T[1] <= T[2]) ? T[1] : T[2]);
return OK;
}