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 |










