第一天
数据结构
linux基础几乎全部是记忆的。数据结构大部分全部是理解的,慢慢培养逻辑思维。学习数据结构:养成好的编程习惯,并且在这门课学会函数传参
数据结构必然会联系算法。
什么是所谓的数据结构?
1、什么是数据?
数值型数据(整数,实数,字符)
非数值型数据(文字、图片、视频、声音)
计算机存储设备能够识别的符号。
2、数据还包含了一个很重要的概念:数据元素。
数据元素是数据的基本单位。
例子:人,每个人是一个数据元素,每个人有两个眼睛,一个鼻子...(数据项)
数据元素又被称为节点/结点。
数据项又被称为域、字段、属性。
struct student
{
char name[15];
int id;
int score;
};
struct student str[5];结构体数组就是所谓的数据
每个数组元素就是上面的数据元素。
name、id、score都是数据项。
3、数据类型
什么是结构?
struct student str[5]在内存中给这个数组分配空间。
直接在栈区中分配。栈区中分配特性:线性的,不同的数据元素是连续的。
假设有1000个人需要分配空间?理论来说应该在栈区中分配一个1000个元素的数组空间。栈区空间会不足。
所以哪里有空间就在哪里分配,这就是后面重点讲的链表。
上面两种情况都属于线性关系。
层次结构:树
网状结构:图
最终目的将数据结构存放到内存中?如何操作呢?
有三种工作需要操作:逻辑结构、存储结构、数据运算
逻辑结构:是人的想法,在计算机中并不存在。
线性关系:线性表(顺序表、链表)、栈、队列
非线性关系:树、图
存储结构:顺序存储结构、链式存储结构、索引存储结构、散列存储结构
重点关心的是前面两个。
顺序存储:在内存中开辟一段连续的空间,相应的数据元素在逻辑上是连续的,并且同时在物理上也是连续的。
链式存储:在内存以数据元素(节点)为单位来开辟空间,不同的节点空间可能连续可能不连续。
顺序存储和链式存储的对比:
1、空间利用率:顺序表只需要存储数据,链表除了要存储数据还需要开辟空间存储下个节点的地址。
2、数据的获取:顺序表存取数据时比较灵活(直接调用数组下标),链式存储必须要知道首元素的地址。
顺序表如果添加元素,那么后续元素依次往后偏移。链表在插入元素时只需要找到要插入的前一个节点地址,其他所有节点都不需要偏移。
索引存储结构:在原有数据的基础上建立了一个索引表,每个索引表都包含很多的索引项。
散列存储
数据运算:增删改查
总结:数据结构将元素以及元素的关系存储到内存中。
算法:编写程序,使计算机能解决问题的方法。
高斯算法。
1 + 2 ... + 100
int i;
for(i = 1;i <= 100;i +)
{
sum += i;
}
上面就是解决问题的一种方法,但是效率很低。
sum = 1 + 2 ... + 100
sum = 100 + 99 ...+ 1
2*sum = 100 * 101 ==》sum = 100 * 101 / 2 公式 sum = n*(n + 1)/2
第二种方式也是一种算法。
两种对比发现:算法有优劣性。
注意:算法永远不可能是通用的。
算法特性:
输入:可以有0个可以有多个
输出:至少要有1个输出
有穷性:一种算法在运行时要在有限的步骤内结束。平时经常会写while(1),很多虽然是无限循环,但是我们有退出条件。
如果一个程序执行了100年再结束,那这个程序没有任何意义。
确定性:一个程序运行时不能造成二义性。
可行性:就是执行代码可以被cpu识别。
如何评估一个算法的好坏?
1、时间复杂度:考虑这个问题时都把数据量想象成无限大。
一个算法在计算机上执行时耗费的时间,写程序过程中不可能直接看时间,程序的语句越多执行的时间就越多。
语句执行频度:每条代码重复执行的次数。
时间复杂度:所有语句重复执行次数的和。数学中被标识为T(n);
T(n) = O(f(n)) 这里的=不是相等,也不是赋值的意思,是趋近于。
描述为T(n)趋向于O(f(n));
T(n) = 2n3+3n2+2n+3
O(f(n)) = O(n3) 当n趋于无穷大时。
大O法被叫做渐进时间复杂度,很多时候简称为了时间复杂度。
2、空间复杂度
一个算法在运行时占用了三个空间:源码本身占用内存、输入输出占用内存、运行时临时占用的内存
运行时临时占用的内存是空间复杂度。空间复杂度越高占用的临时内存就越高。
注意:时间复杂度和空间复杂度相当于鱼和熊掌不可兼得。
3、可读性 写的程序自己用2分钟看懂了,其他所有人用了2天。
4、健壮性 尽可能的减少bug出现。
线性表:
顺序存储结构。
链式存储结构。
顺序表类型:
typedef struct
{
int buf[100];
int n;//代表数组的下标
}seqlist;
1、给线性表分配空间。
seqlist *l;
l = (seqlist *)malloc(sizeof(seqlist));
l->n = -1;//代表现在分配的空间是空的。
如何按位置插入?
insert_assign_data(l,100,2);//比如在数组的第2个位置插入数据100。
1、循环移位多少次?
2、写循环操作
前一个位置的数据放到后一个位置。
3、循环结束后第二个位置已经空出
将100赋值到第二个位置
4、更新数组最后一个元素的下标值。
1 2 3 4 5 6 7 8 9 10
1 100 2 3 4 5 6 7 8 9 10
如何删除所有指定的元素?
delete_assign_data(l,4);//删除顺序表中所有值为4的元素