数据结构我悟了

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

队列,栈,线性表为线性结构,二叉树不是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值