为什么要学习数据结构
学习编程语言是为了写代码进而实现目的,学习数据结构是为了简洁高效的
写程序
解决实际问题需要考虑:
数据如何输入到计算机并且在计算机中以何种形式存储:数据结构
如何根据计算机中的数据进行处理:算法
程序=数据结构+算法
【数据结构】
数据:能够输入到计算机并且被计算机处理的信息的总和
结构:数据与数据之间的关系
数据元素:类似于一个集合的概念,数据总和里的一个个体,是数据
的基本单位
数据项:数据有意义的最小单位
节点:数据元素又被称为节点
数据结构:数据的逻辑结构、存储结构以及相关运算
逻辑结构:数据与数据之间的固有关系,和存储位置无关
1.线性结构:元素之间是一对一的关系,每一个元素最多有一个前驱和一个后继
表头无前驱,表尾无后继
图书管理
2.层次结构(树形结构):每一个节点最多有一个前驱但是可以有多个后继
族谱、下棋走向
3.图形结构(网状结构):每一个节点可以和多个节点产生关联
人际关系网,路口道路选择问题
存储结构:
顺序存储:数据与数据之间内存连续
链式存储:数据与数据之间内存不一定连续。靠指针维系关系
索引存储:存在两张表,索引表和数据表,根据索引项从索引表中找到索引项
在数据表中对应的位置
散列存储:哈希存储 存在一个散列函数和一个关键之key,将key带入
散列函数,能够计算出key值对应数据存储位置
相关操作:增删改查等操作
【算法】解决问题的思想
算法和程序:
程序的实现依赖于算法
算法的特点:
有穷性:算法在执行有限次后可以结束程序
可行性:通过算法写程序可以完成功能的实现
确定性:算法中每一个语句的定义都是确定的,不能存在二义性
输入和输出:每一个程序都有一个或多个输入和输出
衡量好算法的标准:
正确性:保证算法能够正确的完成功能的实现
易读性:算法容易被解读
健壮性:错误处理
高效性:算法执行效率,算法执行快慢容易受到计算机性能的
影响,所以不可以作为评判高效性的标准,这里用可执行语句重复
执行的次数来衡量高效性//时间复杂度
低存储性:算法占用空间小//空间复杂度
【时间复杂度】:(程序运行的速度)
算法的可执行语句重复执行的频度和
语句频度: 算法中可执行语句重复执行的次数
int sum = 0,i = 1;
for(i = 1;i<=100;i++)
{
sum+=i; 100
}
通常时间复杂度用一个问题规模函数来表达 (通过代码执行的次数来衡量)
T(n) = O(f(n))
T(n):问题规模的时间函数
n : 代表的是问题的规模 输入数据 量的大小
例子:冒泡排序 :int a[200];//问题规模就是200
O:时间数量级
f(n) :算法中可执语句重复执行的次数 用问题规模n的某个函数f(n)来表达
例子1:求1+2+3+...+n和
算法1:
int sum = 0,i = 1;
for(i = 1;i<=n;i++)
{
sum+=i; //n T(n) = O(n)
}
算法2:
n*(n+1)/2 //T(n)=O(1)
例子2:
int i,j;
for(i = 1;i<=n;i++)
{
for(j = 1;j<=n;j++)
{
printf("hello\n"); T(n) = O(n^2);
}
}
例子3:
int i,j;
for(i = 1;i<=n;i++)
{
for(j = 1;j<=i;j++)
{
printf("hello\n");
}
}
i 次数
1 1
2 2
3 3
...
n n
f(n) = n*(n+1)/2 = n^2/2+n/2
时间数量级:把多项式除了最高次项外其他的去掉,把最高次项系数去掉
例子:国王与麦子
1 2 4 8....2^63
2^n
n^n
面试题: 求几种排序算法的时间复杂度
【空间复杂度】
算法占用的空间大小。一般将算法的辅助空间作为衡量空间复杂度的标准。
算法占用的存储空间包括:
1)输入输出数据所占空间
2)算法本身所占空间
3)额外需要的辅助空间
void change(int *a,int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
输入输出数据所占空间是必须,算法本身所占空间可以通过精简算法来缩减,
而在运行时候使用的辅助变量所占空间,即辅助空间是衡量空间复杂度的关键因素。
【线性表】逻辑线性的数据结构,每一个节点最多有一个前驱和一个后继
表头无前驱,表尾无后继
顺序表、链表、栈、队列
【顺序表】顺序存储数据的线性表,可以对表实现增删改查等操作
操作:
1.创建顺序表
2.判断表是否为空
3.判断表是不是满
4.判断表是否存在
5.插入数据
6.删除数据
7.按照位置查询数据
8.按照数值查询数据
9.按照位置修改数据
10.按照数值修改数据
11.遍历顺序表
12.清空表
13.销毁表