图的遍历和最小生成树
图的遍历及最小生成树
深度优先搜索
假设初始状态是图中所有顶点未曾被访问,则深度优先搜索
可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点
出发深度优先遍历图
,直至图中所有和v有路径相通的顶点都被访问;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点.
Boolean visited[MAX]; //访问标志数组
Status(*VisitFunc)(int v); //函数变量
void DFSTraverse(Graph G,Status(*Visit)(int v)){
/**对图G作深度遍历**/
VisitFunc = Visit ; //使用全局变量VisitFunc,使DFS不必设函数指针参数
for(v=0;v<G.vexnum;++v) visited[v]=FALSE;
for(v=0;V<G.vexnum;++v)
if(!visited[v]) DFS(G,v); //对尚未访问的顶点调用DFS
}
void DFS(Graph G.int v){
//从第v个顶点出发递归地深度优先遍历图G.
visited[v] = TRUE; VisitFunc(v); //访问第v个顶点
for( w = FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))\
if(!visited[w]) DFS(G,w);
}
广度优先搜索
假设从图中某顶点v出发,在访问了v之后依次访问v地各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点.并使"先被访问的顶点的邻接点
"先于"未后被访问的顶点的邻接点
"被访问,直至图中所有已被访问的顶点的邻接点都被访问到.若此时图中尚有未被访问到的顶点,则从尚未被访问到的顶点作为起始点
,重复上述过程.
void BFS_AM(AMGraph &G,char v0)
{
/*从v0元素开始访问图*/
int u,i,v,w;
v = LocateVex(G,v0); //找到v0对应的下标
printf("%c ", v0); //打印v0
visited[v] = 1; //顶点v0已被访问
q.push(v0); //将v0入队
while (!q.empty())
{
u = q.front(); //将队头元素u出队,开始访问u的所有邻接点
v = LocateVex(G, u); //得到顶点u的对应下标
q.pop(); //将顶点u出队
for (i = 0; i < G.vexnum; i++)
{
w = G.vexs[i];
if (G.arcs[v][i] && !visited[i])//顶点u和w间有边,且顶点w未被访问
{
printf("%c ", w); //打印顶点w
q.push(w); //将顶点w入队
visited[i] = 1; //顶点w已被访问
}
}
}
}
最小生成树
在一个连通网的所有生成树中,各边的代价之和最小的那棵生成树称为该连通网的
最小代价生成树(MinimumCost Spanning Tree)
, 简称为最小生成树
。
普里姆算法
把顶点分成两个类型:一个已经访问的顶点集合U,一个未访问的顶点集合V-U
在实际运行时,可以通过建立一个visited数组,用true和false来分类两个集合中的顶点。
/**
* 通过普利姆算法获取图形的最小支撑树
*
* @param vertex 普利姆算法的起始顶点
* @return 返回当前图形的最小支撑树,注意:这要求当前图形是连通图
*/
public MinTree prim(int vertex) {
boolean[] visited = new boolean[numberOfVertex];
Arrays.fill(visited, false);
// 表示vertex结点已经加入最小支撑树
visited[vertex] = true;
MinTree minTree = new MinTree(numberOfVertex);
// 感觉这个过程还是不太好理解。
// 注意选择排序的运用
while (minTree.numberOfMstEdge() < numberOfVertex - 1) {
MSTEdge edge = getShortestEdge(visited);
minTree.addMstEdge(edge);
visited[edge.getEnd()] = true;
}
return minTree;
}
/**
* 获取已访问顶点和未访问顶点之间相连的最短边
* @param visited 辅助遍历数组
* @return 获取最短边,一端是已经访问的点,一端是未访问的顶点。通过遍历求出最短的边
*/
private MSTEdge getShortestEdge(boolean[] visited) {
int minWeight = Integer.MAX_VALUE;
int minStart = Integer.MAX_VALUE;
int minEnd = Integer.MAX_VALUE;
// i 表示已经访问过的集合中的顶点
for (int i = 0; i < numberOfVertex; i++) {
// 表示未访问的顶点集合中的顶点
for (int j = 0; j < numberOfVertex; j++) {
if (visited[i] && !visited[j] && edges[i][j] < minWeight) {
minWeight = edges[i][j];
minStart = i;
minEnd = j;
}
}
}
return new MSTEdge(minStart, minEnd, minWeight);
}
class MinTree {
ArrayList<MSTEdge> mstEdges;
public MinTree(int numberOfVertex) {
mstEdges = new ArrayList<>(numberOfVertex - 1);
}
public void show() {
System.out.println("MinTree.show");
System.out.println("最小支撑树如下所示:");
mstEdges.stream()
.forEach(System.out::println);
}
public void addMstEdge(MSTEdge mstEdge) {
mstEdges.add(mstEdge);
}
public int numberOfMstEdge() {
return mstEdges.size();
}
}
class MSTEdge {
int start;
int end;
int weight;
public MSTEdge(int start, int end, int weight) {
this.start = start;
this.end = end;
this.weight = weight;
}
@Override
public String toString() {
return "MSTEdge{" +
"start=" + start +
", end=" + end +
", weight=" + weight +
'}';
}
public int getEnd() {
return end;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】