第六章:general trees
要求&笔记
概念:traversal,Equivalence classes
应用题:树的存储表示,树和二叉树的转换
看懂:traversal/UNION/FIND 几个操作的实现思想
General Tree Denitions and Terminology
◼ General Tree :a tree whose nodes have an arbitrary number of childern
◼ A forest is a collection of one or more trees
General Tree Traversal(和二叉树差不多的)
◼ Preorder traversal first visits the root of the tree, then performs a preorder traversal of each subtree from left to right.
◼ Postorder traversal performs a postorder traversal of the root’s subtrees from left to right, then visits the root.
eg.
应用题见作业
第十一章:graph
要求&笔记
概念:path, cycle, connected component, complete graph, BFS, DFS, DAG, MST
应用题:
图的存储方式(Adjacent list/matrix),BFS/DFS 遍历过程,不同的拓扑排序算法过程, 最 短路径(Dijkstra 算法)的构造,MST (Prim/Kruskal 算法)的构造
算法:Adjacent list/matrix 存储结构下图的基本操作,Dijkstra/Prim/Kruskal 算法
Path: A sequence of vertices v1, v2, …, vn of length n-1 with an edge from vi to vi+1 for 1 <= i < n.
cycle: cycle is a path of length 3 or more that connects vi to itself.(闭环
(图2,3均为subgraph)
图有两种表现形式:矩阵 链表list
空间复杂度分别为:(|V|2). (|V| + |E|)
space efficiency depends on the number of edges in the graph.
eg.
矩阵与链表的代码实现
矩阵:(我感觉可能考的概率不大,)链表在这里也不写了,看其他文章的大题作业/试卷
// Graph abstract class. This ADT assumes that the number
// of vertices is fixed when the graph is created.
class Graph {
// Return: the number of vertices and edges
virtual int n() =0;
virtual int e() =0;
// Return v’s first neighbor
virtual int first(int v) =0;
// Return v’s next neighbor
virtual int next(int v, int w) =0;
//还有其他函数功能
}
// Implementation for the adjacency matrix representation
class Graphm : public Graph {
private:
int numVertex, numEdge; // Store number of vertices, edges
int **matrix; // Pointer to adjacency matrix!
int *mark; // Pointer to mark array
public:
Graphm(int numVert) // Constructor
{ Init(numVert); }
˜Graphm() { // Destructor
delete [] mark; // Return dynamically allocated memory
for (int i=0; i<numVertex; i++)
delete [] matrix[i];
delete [] matrix;
}
void Init(int n) { // Initialize the graph
int i;
numVertex = n;
numEdge = 0;
mark = new int[n]; // Initialize mark array
for (i=0; i<numVertex; i++)
mark[i] = UNVISITED;
matrix = (int**) new int*[numVertex]; // Make matrix
for (i=0; i<numVertex; i++)
matrix[i] = new int[numVertex];
for (i=0; i< numVertex; i++) // Initialize to 0 weights
for (int j=0; j<numVertex; j++)
matrix[i][j] = 0;
}
int n() { return numVertex; } // Number of vertices
int e() { return numEdge; } // Number of edges
// Return first neighbor of "v"
int first(int v) {
for (int i=0; i<numVertex; i++)
if (matrix[v][i] != 0) return i;
return numVertex; // Return n if none
}
// Return v’s next neighbor after w
int next(int v, int w) {
for(int i=w+1; i<numVertex; i++)
if (matrix[v][i] != 0)
return i;
return numVertex; // Return n if none
}
// Set edge (v1, v2) to "wt"
void setEdge(int v1, int v2, int wt) {
Assert(wt>0, "Illegal weight value");
if (matrix[v1][v2] == 0) numEdge++;
matrix[v1][v2] = wt;
}
void delEdge(int v1, int v2) { // Delete edge (v1, v2)
if (matrix[v1][v2] != 0) numEdge--;
matrix[v1][v2] = 0;
}
bool isEdge(int i, int j) // Is (i, j) an edge?
{ return matrix[i][j] != 0; }
int weight(int v1, int v2) { return matrix[v1][v2]; }
int getMark(int v) { return mark[v]; }
void setMark(int v, int val) { mark[v] = val; }
};
Graph Traversals:Depth-First Search(DFS)Breadth-First Search(BFS)Topological Sort(TS)
if the graph is not connected ,not all the vertices can be reach
make sure cycles not cause infinite loop(陷入循环)
深度优先检索(DFS)
思想:
1、访问出发点v。
2、找出刚访问过的顶点的第一 个未被访问的邻接点,然后 访问该顶点。以该顶点为新 顶点,重复此步骤,直到刚 访问过的顶点没有未被访问的邻接点为止。 (等几率的话优先小的接近的
3、返回前一个访问过的且仍有 未被访问的邻接点的顶点, 找到该顶点的下一个未被访 问的邻接点,访问该顶点; 然后执行步骤2
eg.
(注:所有顶点加上标有实线箭头的边,构成一颗以A为根的树,称 为深度优先搜索树(The depth-first search tree
算法:
访问出发点v。 依次以v的未被访问的邻接点为出发 点,深度优先搜索图,直至图中所 有与v有路径相通的顶点都被访问。重复上述深度优先搜索过程,直至 图中所有顶点均被访问过为止(非连通图,看大程序)
breadth First search
BFS基本思想(类似于树的层次周游)
1、从图中某个顶点v出发,首先访问v
2、 依次访问v的各个未被访问的邻接点(还是等概率的情况下先小的接近的
3、分别从这些邻接点出发,依次访问它们的各个未被 访问的邻接点。
(访问时保证:如果vi和vk为当前端结点,且vi在vk之前被访 问,则vi的所有未被访问的邻接点应在vk的所有未被访问 的邻接点之前访问。
4、重复上一步,直至所有顶点均被访问过为止。
应用:
注意用队列的形式画出,可以比图中更加详细
The process of laying out the vertices of a DAG in a linear order to meet the prerequisite rules is called a topological sort.
画图要求同理上面,就是一个个拆解(入队出队
问题:最短路径
算法:
1、Dijkstra’s algorithm
对于图G=(V,E),将图中的顶点分成以下两组。
第一组S:已经求出最短路径的顶点集合(开始为{V0})。
第二组V-S:尚未求出最短路径的顶点的集合(开始为V – {V0}的全部 结点)。
算法: 按最短路径长度的递增顺序逐个将第二组的顶点加入到第一组中 ,直到所有顶点都被加入到第一组顶点集S为止。
应用:
注:只能检索到第一个有可行方向的连接,如A:ABCD,B:D,C:BE
代码实现:
// Compute shortest path distances from "s".
// Return these distances in "D".
void Dijkstra(Graph* G, int* D, int s) {
int i, v, w;
for (int i=0; i<G->n(); i++) // Initialize
D[i] = INFINITY;
D[0] = 0;
for (i=0; i<G->n(); i++) { // Process the vertices
v = minVertex(G, D);
if (D[v] == INFINITY) return; // Unreachable vertices
G->setMark(v, VISITED);
for (w=G->first(v); w<G->n(); w = G->next(v,w))
if (D[w] > (D[v] + G->weight(v, w)))
D[w] = D[v] + G->weight(v, w);
}
}
int minVertex(Graph* G, int* D) { // Find min cost vertex
int i, v = -1;
// Initialize v to some unvisited vertex
for (i=0; i<G->n(); i++)
if (G->getMark(i) == UNVISITED) { v = i; break; }
for (i++; i<G->n(); i++) // Now find smallest D value
if ((G->getMark(i) == UNVISITED) && (D[i] < D[v]))
v = i;
return v;
}
//从未被访问的顶点中找距离最小
2、Floyd算法
3、Prim算法