学习流程主要包括分为11个部分
- 绪论
- 线性表
- 栈和队列
- 递归和分治思想
- 串(KMP算法)
- 数组和广义表
- 树和二叉树
- 图
- 动态存储管理
- 查找
- 排序
一 绪论
1.1 数据结构:是相互之间存在一种或者多种特定关系得数据元素得集合。根据元素之间关系的不同特性,通常有四类基本结构:
1.集合:构成元素之间除了同属一一个集合得关系之外,没有其他关系
2.线性结构:结构中得数据元素之间存在一个对一个的关系
3.树形结构:结构中数据元素之间存在一个对多个的关系
4.图装结构和网状结构:结构中得数据元素之间存在多个对多个的关系
1.2 抽象数据类型(ADT)(Abstract Data Type) 可以用以下三元组表示
(D,S,P)
ADT 抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
数据操作:<数据操作的定义>
}
如:
ADT Triplet{
数据对象:
数据关系:
基本操作:
InitTriplet(&T,v1,v2,v3){
操作结果:构造三元组T,
}
DestroyTriplet(&T){
操作结果:销毁T,
}
Get(T,i,&e){
初始条件: 三元组已经存在
操作结果:用e返回T的i元值
}
Put(&T,i,e){
初始条件: 三元组已经存在
操作结果:改变T的i元值为e
}
IsAscending(T){
升序排列
}
IsDescending(T){
降序排列
}
Max(T,&e){
e返回最大值
}
Min(T,&e){
e返回最小值
}
}
1.3 算法
1.3.1 算法的特性:有穷性,确定性,可行性,输入,输出
1.3.2 算法设计要求:正确定 可读性 健壮性 效率与地存储量需求
1.3.3 算法效率的度量(时间复杂度): 算法执行时间需要通过算法编制程序在计算机上运行时消耗的时间来度量。
一个算法是由控制结构(顺序,分支,循环)和原操作 构成。算法的时间取决于两者的综合效果。一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数f(n),算法的时间量度记作:
他表示随着问题规模n的增大,算法执行时间的增长率和的增长率相同,称作算法的时间复杂度。
{++x;s=0;} //程序1
for(i=0;i<n;i++){++x;s+=x;} //程序2
for(i=0;i<n;i++) //程序3
for(j=0;j<n;j++){++x;s+=x;}
上述三个程序段中含基本操作 ++x的频度分别为 1,, 对应的时间复杂度为,,,分别成为常量阶,线性阶,和平方阶。算法还可以呈现的时间复杂度有对数阶,指数阶等等。我们应尽可能选择多项式阶的算法,而不希望指数阶的算法.
由于算法的时间复杂度考虑的只是问题规模n的增长率,则难以精确计算基本操作执行的次数的情况下,只需求出它关于n的增长率或阶即可
for(i=2;i<=n;++i)
for(j=1;j<=n;++j){
++x;
a[i][j]=x;
}
语句++x的执行次数关于n的增长率为,它是语句频度表达式中增长最快的项。
有的情况,算法的基本操作重复执行的次数还随着输入数据集不同而不同,例如再冒泡排序算法中
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
// 交换位置
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
指针实现:
void bubbleSort(int *arr, int n) {
int *p, *q, temp;
for (p = arr; p < arr + n - 1; p++) {
for (q = arr; q < arr + n - 1 - (p - arr); q++) {
if (*q > *(q + 1)) {
// 交换位置
temp = *q;
*q = *(q + 1);
*(q + 1) = temp;
}
}
}
}
交换序列中相邻两个整数位基本操作,数组arr中序列为从小到大有序,那么操作执行的次数为0;当初始数组,从大到小有序执行次数为。对这类算法,是计算平均值,即计算它的平均时间复杂度。假设arr数组中初始输入数据可能出现所有情况即种的排列,概率相等,则冒泡法的平均时间复杂度为。
然而。在很多情况下,各种输入的数据集难以确定,计算平均时间复杂度也就难以确定。因此另外一种可行也是最常用的方法是讨论算法在最坏情况下的时间复杂度,即分析最坏情况,以估计算法执行时间的一个上界。因此冒泡法的最坏情况下的时间复杂度为。
1.3.4 算法的存储空间需求
类似于时间复杂度,我们以空间复杂度作为算法所需存储空间的度量记作:
其中n为问题的规模或者大小,又如所占空间量依赖特定的输入,则除特别指明外,输入数据所占空间均按最坏情况来计算。