数据结构基础
是指相互之间存在一种或多种特定关系的数据元素的集合用计算机存储、组织数据的方式。
基本术语
- 数据: 是可以被自算计处理的符号或符号集合
- 数据对象: 性质相同的数据元素的集合(类似于数组)
- 数据元素: 组成数据的对象的基本单位
- 数据项: 组成数据元素的最小单位
- 数据元素之间不是独立的,存在特定的关系。这些关系即是结构
数据类型: 是指⼀组性质相同值的集合以及定义在此集合的⼀些操作的总称。
在C语⾔中,按照取值不同,数据类型可以分为2类:
- 原⼦类型: 是不可以在分解的基本数据类型,包含整型,浮点型,字符型等;
- 结构类型: 由若⼲类型组合⽽成,是可以再分解的.例如,整型数组就是由若⼲整型数据组成的。
逻辑结构:指在数据中数据元素之间的相互关系。分为:线性结构和非线性结构
线性结构的的特点:
- 存在唯⼀一的⼀一个被称作”第⼀一个”的数据元素
- 存在唯⼀一的⼀一个被称作”最后⼀一个"的数据元素
- 除了了第⼀一个之外,结构中的每个数据元素均有⼀一个前驱
- 除了了最后⼀一个之外,结构中的每个数据元素都有⼀一个后继
主要表现形容包括链表,数组,字典,栈,队列,字符串,线性表,其中队列,栈是特殊的线性结构(主要特殊在读取方式)。
非线性结构:
- 集合结构、树形结构、图形结构
- 集合结构: 元素之间没有特殊的关系,只是属于一个集合
- 树形结构: 一对多的关系,比如二叉树,红黑树等
- 图形结构: 多对多的关系,如矩阵表等
物理结构:数据的逻辑结构在计算机中的存储形式
- 顺序存储结构: 数据元素存放在一组存储地址连续的存储单元里,其数据元素间的逻辑关系和物理关系是一致的
- 链式存储结构: 数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的
数据结构与算法关系
- 什么是算法?
算法就是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,冰球每个指令表示一个或多个操作。
- 算法特性
1.输入输出:必须有输入和输出结果
2.有穷性:算法可以在有限次的执行下得到结果而不是出现无限循环
3.确定性:算法执行的每一步骤在一定条件下只有一条执行路径,一个相同的输入对应相同的一个输出
4.可行性:算法每一步骤都必须可行,能够通过有限的执行次数完成
- 算法设计要求
1.正确性:不能有语法错误
2.可读性:正确合理注释代码
3.健壮性:异常判断及相应提示,比如下标越界,输入值符合标准等
4.时间效率高和储存量低
- 算法的效率度量包括:时间复杂度和空间复杂度
算法复杂度计算:大O表示法
- 用常数1取代运行时间中所有常数 3->1 O(1)
- 在修改运行次数函数中,只保留最高阶项 n3+2n2+5 -> O(n^3)
- 如果在最高阶存在且不等于1,则去除这个项目相乘的常数 2n^3 -> n^3
常见的时间复杂度
常数阶
/* 1. 常数阶时间复杂度计算 O(1) */
//1+1+1 = 3 O(1)
void testSum1(int n){
int sum = 0; //执行1次
sum = (1+n)*n/2; //执行1次
printf("testSum1:%d\n",sum);//执行1次
}
线性阶
/*2.线性阶*/
//x=x+1; 执行n次 O(n)
void add2(int x,int n){
for (int i = 0; i < n; i++) {
x = x+1;
}
}
对数阶
/*3.平方阶*/
//x=x+1; 执行n*n次 ->O(n^2)
void add3(int x,int n){
for (int i = 0; i< n; i++) {
for (int j = 0; j < n ; j++) {
x=x+1;
}
}
}
对数阶
/*4.对数阶*/
/*2的x次方等于n x = log2n ->O(logn)*/
void testA(int n){
int count = 1; //执行1次
//n = 10
while (count < n) {
count = count * 2;
}
}
立方阶
/*5.立方阶*/
void testB(int n){
int sum = 1; //执行1次
for (int i = 0; i < n; i++) { //执行n次
for (int j = 0 ; j < n; j++) { //执行n*n次
for (int k = 0; k < n; k++) {//执行n*n*n次
sum = sum * 2; //执行n*n*n次
}
}
}
}
算法空间复杂度计算
在考量算法的空间复杂度,主要考虑算法执行时所需要的辅助空间
程序空间计算因素
- 寄存本身的指令
- 常数
- 变量
- 输入
- 对数据进行操作的辅助空间