eof函数
ifstream.eof()读到文件结束符或文件不存在时返回true。文件结束符是文件最后一个字符的下一个字符。
int isaplpaha(int c)
检查所传字符是否字母,若是返回非零值,若否返回0
ifstream
在C++中,对文件的操作是通过stream的子类fstream来实现的,须加入头文件#include<fstream>
open()函数的参数是一个char*类型的量,要通过调用string类的c_str()函数返回一个C风格的字符串(即一个字符数组的首地址)才可以调用
istringstream::istringstream(string str)
从string对象中读取字符,但会包括标点
struct构造函数
如果在struct中定义了构造函数,必须定义一个默认构造函数(无参)才可以进行实例化。不然在new时会出现问题。
struct Test
{
int a;
char *b;
};
Test* test=new Test;//结构体使用默认构造函数,编译通过
struct Test1 {
Test1(int a):_a(a) {}
int _a;
};
Test1* test=new Test1;//没有定义默认构造函数,可以把构造函数改成缺省构造函数
Segmentation fault
常见是下标越界,new
Final
ADT
抽象数据类型是带有一组操作的一些对象的集合,stack,list,queue
优点:
分离定义和实现,这样就可以编写客户端代码,而不必担心实现细节,可能需要修改实现。
算法
算法是一种使用一系列指令来解决问题的方法的描述。
评估算法最重要的指标是时间复杂度。
算法的五个特性
确定性,可行性,输入,输出,有限性
算法的描述方法
自然语言,伪代码,流程图,程序设计语言
栈帧
为每个调用函数分配的临时存储区域,包括返回地址,调用参数,局部变量等
前中后缀表达式
中缀:
正常的
前缀:
栈s1和栈s2,从右到左遍历,遇到数字进栈s2
遇到运算符:
如果s1为空或栈顶为),直接进栈。
如果优先级大于等于栈顶运算符,进栈
否则将s1栈顶运算符弹出压入s2,重复
遇到括号:
右括号)直接进栈
左括号( 将s1栈顶元素依次弹出直到遇到左括号,将这对括号丢弃
最后:将s1剩余元素依次弹出并压进s2,依次弹出s2
后缀:
栈s1和栈s2,从左到右遍历
数字直接进s2
运算符:
栈空或栈顶是(直接进栈
优先级比栈顶高(不包括等于),进s1。否则弹出压进s2
括号:
左括号直接进s1,右括号依次弹出S1栈顶元素并压入s2直到遇到左括号
结果:依次弹出s2元素,逆序!!!
运算符出现顺序就是运算顺序
二分查找
各种二叉树
前中后序遍历
根左右,左根右,左右根
根据前中...构造二叉树,只根据先后无法唯一确定一颗二叉树
完全二叉树
深度为h的二叉树,除了第h层外,其他各层节点数都达到最大,第h层所有的节点连续集中在最左边
堆
最大堆:
父节点比子节点大
最小堆:
父节点比子节点小
第i个节点的父节点为i/2
shift down:
和子节点中较大者交换位置
最大堆转最小堆:
交换1号和n号,从1到n-1重新调整为堆,交换1号和n-1号,...以此类推
堆的排序:
从第n/2个节点,调整其子树,n/2-1...以此类推
heapify:数组的堆化
二叉查找树
对于节点x,左子树都小于x,右子树都大于x
AVL树(平衡二叉树)
每个节点的左子树和右子树高度最多差1的二叉查找树
LL:右旋 RR:左旋 RL:右左 LR:左右
哈夫曼算法(最优二叉树)
一开始存在n棵只有一个节点的树,选取其中两个权值最小的形成一颗新树,新树根节点权值为其和,继续....
WPL=(wi*li)之和
带权路径长度=叶子节点权值wi*树根到叶子节点的路径长度
红黑树(O(logn))
性质:
每个结点不是红就是黑。
根和叶(NIL)是黑色的。
如果一个节点是红色的,那么其父节点就是黑色的。
所有从任意结点x到后代叶结点的简单路径都有相同数量的黑结点。
定理:
一颗n个节点的红黑树高度最大为2log(n+1)
WTF is 比较树?
二分查找的比较树?ppt8
并查集
稳固排序
保持相等元素原来顺序不变
eg.冒泡,插入,合并排序
非稳固排序
选择排序,希尔排序,堆排序,快速排序
冒泡
每一次把最小的搞到最前面
插入
一个一个插
mergesort
两个表合一,先一直分,再合
选择
希尔
5,3,1...
堆排序
从第n/2个节点,调整其子树,n/2-1...以此类推
快速排序
选一个temp哨兵,把比他小的搞到左边,比他大的搞到右边
哈希
常用的哈希函数
直接定址法,除留余数法,平方取中法,折叠法,数字分析法,随机数法
(1)直接定址法 其哈希函数为一次函数,即以下两种形式: H(key)= key 或者 H(key)= a * key + b 其中 H(key)表示关键字为 key 对应的哈希地址,a 和 b 都为常数。
(2)数字分析法 如果关键字由多位字符或者数字组成,就可以考虑抽取其中的 2 位或者多位作为该关键字对应的哈希地址,在取法上尽量选择变化较多的位,避免冲突发生。
(3)平方取中法 平方取中法是对关键字做平方操作,取中间得几位作为哈希地址。此方法也是比较常用的构造哈希函数的方法 例如关键字序列为{421,423,436},对各个关键字进行平方后的结果为{177241,178929,190096},则可以取中间的两位{72,89,00}作为其哈希地址。
(4)折叠法 折叠法是将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址。此方法适合关键字位数较多的情况。
(5)除留余数法 若已知整个哈希表的最大长度 m,可以取一个不大于 m 的数 p,然后对该关键字 key 做取余运算,即:H(key)= key % p。 在此方法中,对于 p 的取值非常重要,由经验得知 p 可以为不大于 m 的质数或者不包含小于 20 的质因数的合数。
解决哈希冲突
链地址法
开放地址:线性探测法,二次探测法
(二次探测法:采用开放定址法处理冲突中的二次探测再散列(也即是题目中的二元探测法),则哈希函数变为Hash(key) = (Hash(key) + d) % 11,其中d = 1^2, -1^2, 2^2, -2^2, 3^2,……,则开始计算。)
删除哈希表元素
一种解决方案是发明另一个特殊的键来表示删除的位置,这个键在插入时为空,但在检索时“不为空”。不然可能再检索与删除元素有冲突的元素时产生错误
图论
概念
完全图,子图,生成子图,连通图,DAG(有向无环图)
极大联通子图:无向图 连通图只有一个极大连通子图(它本身),非连通图有多个。
极小连通子图:能连通图的所有顶点又不产生回路的任何子图(生成树)
强连通图:有向图中每一对顶点v,w都有从v到w和从w到v的路径,有n个顶点的强连通图最多有n(n-1)边,最少有n条边
弱连通图:有向图的基图是连通图
邻接表,邻接矩阵
对于n个顶点e条边的无向图,邻接表中除了n个头结点外,只有2e个表结点,空间效率为O(n+2e)。若是稀疏图(e<<n2),则比邻接矩阵表示法O(n2)省空间。 在有向图中,邻接表中除了n个头结点外,只有e个表结点,空间效率为O(n+e)。若是稀疏图,则比邻接矩阵表示法合适。 邻接表的优点:空间效率高;容易寻找顶点的邻接点; 邻接表的缺点:判断两顶点间是否有边或弧,需搜索两结点对应的单链表,没有邻接矩阵方便。
dfs
bfs
队列
拓扑排序
入度为0,删除,有向无环图,若输出的顶点个数小于全部顶点,不是DAG
欧拉回路
欧拉电=回路只有在图是连通的并且每个顶点有偶数度时才可能存在
A.判断欧拉通路是否存在的方法
如果一个图是连通的并且恰好有两个奇数顶点,那么它就有一条欧拉路径
B.判断欧拉回路是否存在的方法
如果一个图是连通的并且每个顶点都是偶数,那么它就有一个欧拉回路(至少一个,通常更多)。如果一个图有奇数顶点,那么它就没有欧拉电路。
最小生成树(无向图)
prim
用集合来表示:图的所有顶点集合为V,已访问顶点集合为u,未访问顶点集合为UU,选择一个初始顶点加入u集合,在两个集合u和UU组成的边中选择最小的边(u0,UU0)加入最小生成树中,将UU0点加入u,重复上述操作至UU集合为空
kruskal
把图中的n个顶点堪称独立的n棵树组成的森林,按权值从小到大选择边,所选的边连接的两个顶点u,v应该属于两颗不同的树(即没有公共祖先,可采用并查集判断)。则成为最小生成树的一条边,并将这两棵树合并成一棵树。重复上述操作知道有n-1条边为止。
最短路径
dijkstra
floyda
定义一个二维数组distance存储两个城市间的距离,程序开始时将它每个元素初始化为-1,表示两个城市间不存在路径。将输入的边全部存进二维数组。利用内外三个for循环,如果存在从a到b,从b到c的路径(即disa!=-1,disb!=-1),若原先不存在从a到c的路径,将disa+disb存进disa,否则,比较disa+disb与disa的大小,将较小着存进disa。至此,各个城市之间的最短路径均已存进dis数组,i与j城市之间的最短路径即disi
队列,栈,线性表为线性结构,二叉树不是