e
二叉树
二叉树的基本操作
定义二叉树
1  | struct Node{  | 
二叉树结点的插入
1  | //基于二叉树的性质的插入方法  | 
二叉树的建立
1  | Node* Create(int data[],int n){  | 
先序遍历
1  | //递归写法  | 
层序遍历
1  | void Layerorder(Node* root){  | 
1  | 
二叉查找树
寻找root的后继结点
1  | Node* Findnext(Node* root){  | 
寻找root的前驱节点
1  | Node* Findpre(Node* root){  | 
删除以root为根的树中权值为x的结点
1  | //通过一个一个地移动结点来删除结点  | 
AVL树
AVL树的结点
1  | struct Node{  | 
得到树的高度
1  | int getHeight(Node* root){  | 
得到树的平衡因子
1  | int getBalanceFactor(Node* root){  | 
更新树的高度
1  | void updateHeight(Node* root){  | 
这个函数在后面的左旋,右旋和插入操作中要用到。
AVL树的左旋右旋操作
1  | void L(Node* &root){  | 
AVL树的插入操作
只要把最靠近插入节点的失衡结点调整到正常,就好了。
1  | void insert(Node* &root, int v){  | 
AVL树的删除操作
AVL树删除节点的过程是,先找到该节点,然后进行删除。由于删除节点的位置不同,导致删除后节点进行移动的方式不同。删除节点的位置分为以下4类:
- 删除叶子结点。操作:直接删除,然后依次向上调整为AVL树。这种情况下,可能会产生AVL树失衡
 - 删除非叶子节点,该节点只有左孩子。操作:该节点的值替换为左孩子节点的值,然后删除左孩子节点。这种情况下不会产生AVL树失衡的。
 - 删除非叶子节点,该节点只有右孩子。操作:该节点的值替换为右孩子节点的值,然后删除右孩子节点。这种情况下不会产生AVL树失衡的。
 - 删除非叶子节点,该节点既有左孩子,又有右孩子。操作:该节点的值替换为该节点的前驱节点(或者后继节点),然后删除前驱节点(或者后继节点)。这种情况下不会产生AVL树失衡的。
 
第一种情况:


第二种情况:

第三种情况:

第四种情况:


堆
为了方便计算子节点在数组中的位置,第一个元素的下标为1
1  | const int maxn = 100;  | 
向下调整
1  | void downAdjust(int low,int high){  | 
downAdjust算法用于创建堆
1  | void createHeap(){  | 
删除堆顶元素
1  | void deleteTop(){  | 
向堆中添加一个元素
1  | //low一般为1,high为欲调整结点的数组下标  | 
堆排序
1  | void heapSort(){  | 
哈夫曼树
如何得到最终的树的带权路径长度
1  | 
  | 
图
1  | struct Node{  | 
邻接表表示法的BFS与DFS
1  | vector<Node> adj[MAXV];  | 
最短路径
dijkstra算法
1  | const int MAXV;  | 
用pre数组保存路径,然后用DFS来遍历所有的路径,这种Dijkstra+DFS的做法可以适用于编程复杂的情况。
1  | if(d[u]+G[u][v] < d[v]){  | 
此时pre数组可以产生一个递归树,所有叶子结点到根节点的路径确定了从起点到终点的所有最短路径
1  | int optValue; //第二标尺最优值  | 
bellman-ford
dijkstra只适用于正权图的情况,而bellman-ford可以适用于负权图。
1  | //模板代码  | 
SPFA
改进的bellman-ford算法,时间复杂度仅为O(ke)(在无可达负环的情况下)
1  | //伪代码  | 
欧拉路
如果一个无向图中有有n个结点,且度为偶数的结点数也为n,则该图含有欧拉回路;若有n个结点,且度为奇数的点的个数为2,则含有欧拉路;否则,不含有欧拉路
数学运算
分数运算
最大公约数
1  | //由离散数学:a与b的公约数与b与a%b的公约数相等  | 
最小公倍数
1  | int lcm(int a,int b){  | 
Hash
//平方探测法 quadratic probing
1  | 
  | 
1  | //利用 i*i = (i-1)*(i-1) + 2*i - 1  |