寒假前半段学习深入浅出从中我总结了一下几点
一 初步算法
1.排序:
选择排序:是从第一个经过大小值比较,需要对每个数据都要进行比较,来进行排序的,可以解决大部分的排序要求,但是有一个缺点是时间复杂度太高。
冒泡排序:相较于选择排序,其唯一不同就是只比较相邻两个数据,在一定的条件下比选择排序的时间复杂度低,但总体来说时间复杂程度还是太高。
插入排序:从第一个的数值开始进行与之前的数值进行比较,以此进行排序,从而实现有序,同理依次比较还是时间复杂程度低。
以上三个排序方式复杂程度比较高,在用于大数据的情况下会出现超时,所以在用于大数据的情况时可以与二分法联用
2.二分法:
二分法空间复杂程度比较低,但是时间复杂程度低,可以极大地节省时间,在面对超时的情况是可以考虑应用二分法。
条件:必须在有序的数据内应用,无法在无序的数据内应用。
3.暴力枚举
循环枚举:根据所需求量,来规定条件,然后去除重复的量,然后补齐所需要的东西。
这个可以考虑到大部分的条件,但是缺点就是时间复杂程度高,经常超时,所以在一定的情况下可以用二分查找。
4.递归
递归思想为平时做题常遇见的思想,比如说上楼梯,斐波那契数列等,在应用中寻找题目中所给条件的中的规律可以轻松得出所求答案。
5.贪心
对题目中所给的条件进行整合,对最优解优先选择,常与bool函数一起联用。应用在个别条件比较多,所求需要对所给条件进行综合考虑的题目。
其中哈夫曼编码就是对细分的条件进行整合,分为几个大范围,再从大范围内进行细分在一定情况下可以节省计算机运算时间,优化了时间复杂程度。
6.搜索
暴力枚举可以算出所求答案,但所需时间太长,并非最优解,搜索就是从暴力枚举的基础上进行优化的算法。
回溯算法:利用了函数递归枚举。
广度优先搜索:多用于寻找最短路径,比如国际象棋的步数,选择最短路径。
二.简单数据结构
1.线性表
(一)数组:
Vector<定义类型> 数组名 (N,i)//开始有N个初始化为i,可以省略,此时长度为0
数组名.size():返回数组长度
v.push_back(a) :将元素a查到数组v的末尾,并增加数组长度
v.resize(n.m):重新调整v数组的长度为n,若初始大于n则删除多余信息 ,若小于n则新增部分全部初始为m。
优点:在输入两组没有数学关系却需要按照其中顺序输入可以使用push_back。
改文件头改变了数组长度一成不变的现状可以在位置数据量的情况下定义,在往后的使用中随要求来添加长度
(二)栈
一组数据如果a比b早加入,那么b一定先退出,这样的数据结构就是栈
栈的文件头
Stack
s.push(a):将元素a压入栈s中
s.pop():将s的栈项元素弹出//将栈项元素另存然后删去,栈项指向下一个元素
s.top():查询s的栈顶元素
s.size():查询s的元素个数
s,empty():查询s是否为空
(三)队列
队列是一种先进后出的线性表示,其限制是允许在表的一段进行删除运算,另一端进行插入运算
文件头
Queue
q.push(a):将元素a插入队列q的末尾
q.pop():删除队列q的首元素
q.front();查询队列q的首元素
q.back():查询队列q的尾元素
q.size():查询队列q的元素个数
q.empty():查询q是否为空
(四)链表
每个元素知道其前后是谁就可以恢复整个表的排列顺序,利用这样的方式储存元素排列顺序表,成为链表
单链表:每个节点记录自己的后继
双链表:每个节点记录自己的前去和后继
循环单链表:本身是一个单链表,但是最后一个结点的后继为第一个结点,为环形
循环双链表:本身是一个双链表,但是最后一个结点的后继为第一个结点,为环形
块状链表:将若干元素压缩成一块,将其串联
2.二叉树
(一)一个数据内每次分叉不超过两部分的数据为分叉
如果一个结点没有任何子树,则称为叶子结点
二叉树高度为h(层数),若有2的k次方-1个结点,则为完美二叉树
(二)二叉树的遍历:将一棵二叉树从根结点开始,按照顺序,不重复,不遗漏的访问每一个结点。
为了符合按顺序,不重复,不遗漏,所以要进行广度优先搜索
3.集合
(一)连接两个集合并查询:
#include
# define M 5010
int fa[M];
int Find ( int x){
//查询是否是同一集合
If (x==fa[x]) return x;
return fa[x]= Find ( fa[x]);
}
void join ( int c1, int c2){//把两个元素放到一个集合内
int f1= Find ( c1 ),f2 = Find (c2);
if ( f1 ! = f2) fa[f1]=f2;
}
(二)Harsh表
Inline 函数: 栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足所造成的程式出错的问题,函数的死循环递归调用的最终结果就是导致栈内存空间枯竭。
为了解决这个问题,特别的引入了inline,表示为内联函数。
例子:
#define mod 23333
using namespace std;
int n,x, ans;
vector
inline void insert ( int x){
for (int I =0;i if ( linker[ x % mod ][i]== x) return ; linker [ x % mod ]. Push _ back(x);// 把linker 数组变成二元数组并进行插入 ans ++; }



