赞
踩
邻接矩阵:
邻接表:
例如下图:表示出发点从A开始的递归树
深度优先搜索DFS,在树和图中其实本质是一样的,可以说树是一种特殊的图,在二叉树(链式存储结构)中,每个结点含有两个指针,分别指向左、右孩子,当然如果没有左右孩子结点则将该指针域置空。遍历时仅需考虑两种情况:1.往左走进入左子树 2.往右走进入右子树,知道指针域为空,则回溯。而在图中,一个结点可能会连接巨多结点,而每一个结点的出度又不尽相同,所以需要提前在建图的时候把所有顶点存入,那么在接下来的遍历中,依次判断与其他顶点的关系,如果是相连的,就可以从走到该节点,如此往复。当然,遍历要求要做到每个节点不重不漏的访问,那么则需要标记数组的记录,对于非连通图,需要依次枚举各个顶点以确保不重不漏。
完整代码如下:
#include <bits/stdc++.h> using namespace std; const int MVNum = 500; bool visited[MVNum];//标记数组,初始化为未访问false typedef struct { char vexs[MVNum]; int arcs[MVNum][MVNum]; int vexnum, arcnum; }AMGraph; int Locatevex(AMGraph &G, char ch) { for (int i = 1; i <= G.vexnum; ++ i) { if (G.vexs[i] == ch) return i; } return 0; } void CreateUDN(AMGraph &G) { //cout << "请输入点数目和边数:" << endl; cin >> G.vexnum >> G.arcnum;//输入顶点数目和边数,空格隔开 // cout << "请依次输入各个顶点 :" << endl; for (int i = 1; i <= G.vexnum; ++ i) cin >> G.vexs[i];//依次输入各个顶点 for (int i = 1; i <= G.vexnum; ++ i) for (int j = 1; j <= G.vexnum; ++ j) G.arcs[i][j] = 0;//对边初始化 // cout << "请输入两顶点,建立边关系 :" << endl; for (int i = 1; i <= G.arcnum; ++ i) { char v1, v2; cin >> v1 >> v2;//输入两顶点,建立边关系 //寻找两个顶点在存入顶点数组中的位置 int x1 = Locatevex(G, v1); int x2 = Locatevex(G, v2); G.arcs[x1][x2] = G.arcs[x2][x1] = 1; } return; } void DFS(AMGraph &G, int x) { //访问输出该顶点,标记为已访问 cout << G.vexs[x] << ' '; visited[x] = true; for (int j = 1; j <= G.vexnum; ++ j) { //如果与下一个点有联系且没有访问,则访问下一个点 if (G.arcs[x][j] && !visited[j]) DFS(G, G.vex[j]); } return; } int main() { AMGraph G; CreateUDN(G); /* 打印建立的二维矩阵 for (int i = 1; i <= G.vexnum; ++ i) { for (int j = 1; j <= G.vexnum; ++ j) cout << G.arcs[i][j] << ' '; cout << endl; } */ char v; cin >> v;//若为非连通图,则删此行,改DFS为DFS_ALL DFS(G, v); system("pause"); return 0; }
运行结果如下:
void DFS_ALL(AMGraph &G)
{
for (int i = 1; i <= G.vexnum; ++ i)
if (!visited[i]) DFS(G, i);
}
运行结果如下:
//直接把上面的DFS函数改了即可,需要引用头文件stack //#include <stack>或引用万能头文件#include <bits/stdc++.h> void DFS(AMGraph &G, char v) { stack <char> S; S.push(v); while (!S.empty()) { char c = S.top(); S.pop();//取出栈顶元素 int x = Locatevex(G, c);//对该元素定位 if (!visited[x]) { cout << c << " "; visited[x] = true;//输出该元素 for (int j = 1; j <= G.vexnum; ++ j) { if (G.arcs[x][j] && !visited[j]) { //将该元素所有相关联的点入栈 S.push(G.vexs[j]); } } } } return; }
运行结果如下:
运行结果如下:
例如下图:
类似于树的层序遍历,在图中也是一层一层地访问。代码方面直接将DFS非递归中栈改成队列即可,BFS函数如下:(从某点开始)
//需要引用头文件#include <queue> //或引用万能头文件#include <bits/stdc++.h> void BFS(AMGraph &G, char v) { queue <char> Q; Q.push(v); while (!Q.empty()) { char c = Q.front(); Q.pop();//取出队头元素 int x = Locatevex(G, c);//对该元素定位 if (!visited[x]) { cout << c << " "; visited[x] = true;//输出该元素 for (int j = 1; j <= G.vexnum; ++ j) { if (G.arcs[x][j] && !visited[j]) { Q.push(G.vexs[j]); //将该元素所有相关联的点入队 } } } } return; }
运行结果:
完整代码如下:
#include <bits/stdc++.h> using namespace std; const int MVNum = 500, MaxInt = 0x7fffffff; typedef struct { char vexs[MVNum]; int arcs[MVNum][MVNum]; int vexnum, arcnum; }AMGraph; struct Node { char adjvex; int lowcost; }closedge[MVNum]; int Locatevex(AMGraph G, char ch) { for (int i = 1; i <= G.vexnum; ++ i) { if (G.vexs[i] == ch) return i; } return 0; } void CreatUDN(AMGraph &G) { cout << "请输入点数目和边数:" << endl; cin >> G.vexnum >> G.arcnum; char v1, v2; int w; cout << "请依次输入各个顶点编号 :" << endl; for (int i = 1; i <= G.vexnum; ++ i) cin >> G.vexs[i]; for (int i = 1; i <= G.vexnum; ++ i) for (int j = 1; j <= G.vexnum; ++ j) G.arcs[i][j] = MaxInt;//初始化无穷大 cout << "请输入两顶点,建立边关系 :" << endl; for (int i = 1; i <= G.arcnum; ++ i) { cin >> v1 >> v2 >> w; int x1 = Locatevex(G, v1); int x2 = Locatevex(G, v2); G.arcs[x1][x2] = G.arcs[x2][x1] = w; } return; } int Min(AMGraph &G) { int res = MaxInt, x = 0; for (int i = 1; i <= G.vexnum; ++ i) { if (closedge[i].lowcost) { if (closedge[i].lowcost < res) { res = closedge[i].lowcost; x = i; } } } return x; } void MiniSpanTree_Prim(AMGraph &G) { int t = 0; char v; cout << "请输入出发点:" << endl; cin >> v; int k = Locatevex(G, v); for (int j = 1; j <= G.vexnum; ++ j) if (j != k) { closedge[j].adjvex = v; closedge[j].lowcost = G.arcs[k][j]; } closedge[k].lowcost = 0; for (int i = 1; i < G.vexnum; ++ i) { k = Min(G); char u0 = closedge[k].adjvex; char v0 = G.vexs[k]; cout << u0 << ' ' << v0 << endl; closedge[k].lowcost = 0; for (int j = 1; j <= G.vexnum; ++ j) { if (G.arcs[k][j] < closedge[j].lowcost) { closedge[j].adjvex = G.vexs[k]; closedge[j].lowcost = G.arcs[k][j]; } } } return; } int main() { AMGraph G; CreatUDN(G); MiniSpanTree_Prim(G); system("pause"); return 0; } /*测试用例: 6 10 ABCDEF A B 6 A D 5 A C 1 B C 5 B E 3 C D 5 C E 6 C F 4 D F 2 E F 6 */
运行结果如下:
#include <bits/stdc++.h> using namespace std; const int MVNum = 500; bool visited[MVNum]; typedef struct ArcNode { int adjvex; struct ArcNode * nextarc; }ArcNode; typedef struct VNode { char data; ArcNode * firstarc; }VNode, AdjList[MVNum]; typedef struct { AdjList vertices; int vexnum, arcnum; }ALGraph; int LocateVex(ALGraph G, char v) { for (int i = 1; i <= G.vexnum; ++ i) { if (G.vertices[i].data == v) { return i; } } return 0; } void CreateUDG(ALGraph &G) { cout << "请输入点数目和边数:" << endl; cin >> G.vexnum >> G.arcnum;//输入顶点数目和边数,空格隔开 cout << "请依次输入各个顶点 :" << endl; for (int i = 1; i <= G.vexnum; ++ i) { cin >> G.vertices[i].data;//依次输入各个顶点 G.vertices[i].firstarc = NULL; } char v1, v2; for (int k = 0; k < G.arcnum; ++ k) { cin >> v1 >> v2; int i = LocateVex(G, v1); int j = LocateVex(G, v2); ArcNode* p1 = new ArcNode; p1->adjvex = j; p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = p1; ArcNode* p2 = new ArcNode; p2->adjvex = i; p2->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = p2; } return; } void DFS(ALGraph &G, char v) { cout << v << ' '; int x = LocateVex(G, v); visited[x] = true; ArcNode* p = G.vertices[x].firstarc; while (p) { int k = p->adjvex; if (!visited[k]) DFS(G, G.vertices[k].data); p = p->nextarc; } } int main() { ALGraph G; CreateUDG(G); char v; cin >> v;//若为非连通图,则删此行,改DFS为DFS_ALL DFS(G, v); return 0; }
运行结果如下:
void DFS_ALL(ALGraph &G)
{
for (int i = 1; i <= G.vexnum; ++ i) {
if (!visited[i]) {
DFS(G, G.vertices[i].data);
}
}
return;
}
运行结果如下:
void DFS(ALGraph &G, char v) { stack <char> S; S.push(v); while (!S.empty()) { char ch = S.top(); S.pop(); int x = LocateVex(G, ch); if (!visited[x]) { cout << ch << ' '; visited[x] = true; ArcNode* p = G.vertices[x].firstarc; while (p) { int k = p->adjvex; if (!visited[k]) S.push(G.vertices[k].data); p = p->nextarc; } } } }
运行结果如下:
运行结果如下:
将DFS非递归中栈改成队列即可,BFS函数如下:(从某点开始)
void BFS(ALGraph &G, char v) { queue <char> Q; Q.push(v); while (!Q.empty()) { char ch = Q.front(); Q.pop(); int x = LocateVex(G, ch); if (!visited[x]) { cout << ch << ' '; visited[x] = true; ArcNode* p = G.vertices[x].firstarc; while (p) { int k = p->adjvex; if (!visited[k]) Q.push(G.vertices[k].data); p = p->nextarc; } } } }
完整代码如下:
#include <bits/stdc++.h> using namespace std; const int MVNum = 500, MaxInt = 0x7fffffff; typedef struct ArcNode { int adjvex, weight; struct ArcNode * nextarc; }ArcNode; typedef struct VNode { char data; ArcNode * firstarc; }VNode, AdjList[MVNum]; typedef struct { AdjList vertices; int vexnum, arcnum; }ALGraph; struct Node { char adjvex; int lowcost; }closedge[MVNum]; int LocateVex(ALGraph G, char ch) { for (int i = 1; i <= G.vexnum; ++ i) { if (G.vertices[i].data == ch) return i; } return 0; } void CreateUDG(ALGraph &G) { cout << "请输入点数目和边数:" << endl; cin >> G.vexnum >> G.arcnum;//输入顶点数目和边数,空格隔开 cout << "请依次输入各个顶点 :" << endl; for (int i = 1; i <= G.vexnum; ++ i) { cin >> G.vertices[i].data;//依次输入各个顶点 G.vertices[i].firstarc = NULL; } char v1, v2; int w; for (int k = 0; k < G.arcnum; ++ k) { cin >> v1 >> v2 >> w; int i = LocateVex(G, v1); int j = LocateVex(G, v2); ArcNode* p1 = new ArcNode; p1->adjvex = j; p1->weight = w; p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = p1; ArcNode* p2 = new ArcNode; p2->adjvex = i; p2->weight = w; p2->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = p2; } return; } int Min(ALGraph &G) { int res = MaxInt, x = 0; for (int i = 1; i <= G.vexnum; ++ i) { if (closedge[i].lowcost) { if (closedge[i].lowcost < res) { res = closedge[i].lowcost; x = i; } } } return x; } void MiniSpanTree_Prim(ALGraph &G) { int t = 0; char v; cout << "请输入出发点:" << endl; cin >> v; int k = LocateVex(G, v); for (int i = 1; i <= G.vexnum; ++ i) { closedge[i].lowcost = MaxInt; } ArcNode *p = G.vertices[k].firstarc; while (p) { closedge[p->adjvex].adjvex = v; closedge[p->adjvex].lowcost = p->weight; p = p->nextarc; } closedge[k].lowcost = 0; for (int i = 1; i < G.vexnum; ++ i) { k = Min(G); char u0 = closedge[k].adjvex; char v0 = G.vertices[k].data; cout << u0 << ' ' << v0 << endl; closedge[k].lowcost = 0; ArcNode *q = G.vertices[k].firstarc; while (q) { if (q->weight < closedge[q->adjvex].lowcost) { closedge[q->adjvex].adjvex = G.vertices[k].data; closedge[q->adjvex].lowcost = q->weight; } q = q->nextarc; } } return; } int main() { ALGraph G; CreateUDG(G); MiniSpanTree_Prim(G); system("pause"); return 0; } /*测试用例: 6 10 ABCDEF A B 6 A D 5 A C 1 B C 5 B E 3 C D 5 C E 6 C F 4 D F 2 E F 6 */
运行结果如下:
THEEND…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。