7-1.将图以邻接矩阵存储,实现DFS。
code
#include<bits/stdc++.h>
using namespace std;
int book[100], sum, n, e[100][100];
void dfs(int cur){
printf("%d ", cur);
sum++;
if (sum == n)
return;
for (int i = 1; i <= n; i++){
if (e[cur][i] == 1 && book[i] == 0){
book[i] = 1;
dfs(i);
}
}
return;
}
int main(){
int i, j, m, a, b;
printf("请输入顶点数和边数:\n");
scanf("%d%d", &n, &m);
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (i == j)
e[i][j] = 0;
else
e[i][j] = 99999;
for (i = 0; i < m; i++){
printf("请输入第%d条边:\n", i + 1);
scanf("%d%d", &a, &b);
e[a][b] = 1;
e[b][a] = 1;
}
book[1] = 1;
printf("深度优先遍历结果为:");
dfs(1);
return 0;
}
运行截图
7-2.将图以邻接表存储,实现BFS。
code
#include<bits/stdc++.h>
using namespace std;
typedef struct EdgeNode
{
int adjvex;
struct EdgeNode * next;
} EdgeNode;
typedef struct
{
string data;
EdgeNode * firstedge;
} AdjList;
typedef struct
{
AdjList adjList[15];
int numVertex,numEdge;
} GraphAdjList;
int local(GraphAdjList G,string val)
{
for(int i=0; i<G.numVertex; i++)
{
if(G.adjList[i].data==val)
return i;
}
return -1;
}
void CreateGraph(GraphAdjList & G)
{
int i,j,k;
string v1,v2;
EdgeNode * e,* p,*q;
cout<<"请输入顶点数和边数,并以空格隔开:"<<endl;
cin>>G.numVertex>>G.numEdge;
cout<<"请输入顶点的信息:"<<endl;
for(i=0; i<(G.numVertex); i++)
{
cin>>G.adjList[i].data;
G.adjList[i].firstedge=NULL;
}
for(k=0; k<(G.numEdge); k++)
{
cin>>v1>>v2;
i=local(G,v1);
j=local(G,v2);
if(G.adjList[i].firstedge==NULL)
{
e= new EdgeNode;
e->adjvex=j;
e->next=NULL;
G.adjList[i].firstedge=e;
}
else
{
p=G.adjList[i].firstedge;
while(p->next!=NULL)
{
p=p->next;
}
e = new EdgeNode;
e->adjvex=j;
e->next=NULL;
p->next=e;
}
if(G.adjList[j].firstedge==NULL)
{
e= new EdgeNode;
e->adjvex=i;
e->next=NULL;
G.adjList[j].firstedge=e;
}
else
{
p=G.adjList[j].firstedge;
while(p->next!=NULL)
{
p=p->next;
}
e = new EdgeNode;
e->adjvex=i;
e->next=NULL;
p->next=e;
}
}
}
void Prin(GraphAdjList G)
{
cout<<"所建立的邻接表如以下所示:"<<endl;
for(int i=0; i<G.numVertex; i++)
{
cout<<G.adjList[i].data;
EdgeNode * e = G.adjList[i].firstedge;
while(e)
{
cout<<"-->"<<e->adjvex;
e=e->next;
}
cout<<endl;
}
}
bool DFSvisited[50];
bool BFSvisited[50];
void DFS(GraphAdjList G,int i)
{
EdgeNode * p;
DFSvisited[i]=true;
cout<<G.adjList[i].data<<" ";
p=G.adjList[i].firstedge;
while(p)
{
if(!DFSvisited[p->adjvex])
DFS(G,p->adjvex);
p=p->next;
}
}
void DFSTraverse(GraphAdjList G)
{
for(int i=0; i<G.numVertex; i++)
DFSvisited[i]=false;
for(int i=0; i<G.numVertex; i++)
{
if(!DFSvisited[i])
DFS(G,i);
}
}
void BFSTraverse(GraphAdjList G)
{
EdgeNode * p;
queue<int>q;
for(int i=0; i<G.numVertex; i++)
BFSvisited[i]=false;
for(int i=0; i<G.numVertex; i++)
{
if(!BFSvisited[i])
{
BFSvisited[i]=true;
cout<<G.adjList[i].data<<" ";
q.push(i);
while(!q.empty())
{
int count =q.front();
q.pop();
p=G.adjList[count].firstedge;
while(p)
{
if(!BFSvisited[p->adjvex])
{
BFSvisited[p->adjvex]=true;
cout<<G.adjList[p->adjvex].data<<" ";
q.push(p->adjvex);
}
p=p->next;
}
}
}
}
}
int main(){
GraphAdjList G;
CreateGraph(G);
Prin(G);
cout << "BFS:" << endl;
BFSTraverse(G);
return 0;
}
运行截图
7-3. 将图以邻接矩阵存储,实现prim算法。
code
#include <bits/stdc++.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
#define INFINITY 65535
#define MAX_VERTEX_NUM 20
typedef int Status;
typedef int VRType;
typedef char InfoType;
typedef int VertexType;
typedef enum
{
DG,
DN,
UDG,
UDN
} GraphKind;
typedef struct ArcCell
{
VRType adj;
InfoType *info;
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct
{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
GraphKind kind;
} MGraph;
typedef struct
{
VertexType adjvex;
VRType lowcost;
} CLOSEDGE;
Status CreateUDN(MGraph *G);
int LocateVex(MGraph G, VertexType v);
int minimum(CLOSEDGE closedge[], int n);
void MiniSpanTree_PRIM(MGraph G, VertexType u);
Status CreateUDN(MGraph *G)
{
printf("\n构造无向网\n");
int i, j, k;
int w;
VertexType v1, v2;
printf("请输入顶点个数:");
scanf("%d", &(*G).vexnum);
printf("请输入弧个数:");
scanf("%d", &(*G).arcnum);
int IncInfo = 0;
cout << "依次输入顶点(空格隔开):\n";
for (i = 0; i < (*G).vexnum; i++){
scanf("%d", &(*G).vexs[i]);
}
for (i = 0; i < (*G).vexnum; i++)
for (j = 0; j < (*G).vexnum; j++)
{
(*G).arcs[i][j].adj = INFINITY;
(*G).arcs[i][j].info = NULL;
}
printf("请输入弧头(初始点)、弧尾(终端点)、权值:\n");
for (k = 0; k < (*G).arcnum; k++){
scanf("%d%d%d", &v1, &v2, &w);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
if (i >= 0 && j >= 0)
(*G).arcs[i][j].adj = (*G).arcs[j][i].adj = w;
}
(*G).kind = UDN;
return OK;
}
int LocateVex(MGraph G, VertexType v)
{
int ct;
for (ct = 0; ct < G.vexnum; ct++)
if (G.vexs[ct] == v)
return ct;
return -1;
}
int minimum(CLOSEDGE closedge[], int n)
{
int i = 0, j, min, k;
while (!closedge[i].lowcost)
i++;
min = closedge[i].lowcost;
k = i;
for (j = 1; j < n; j++)
if (closedge[j].lowcost)
if (min > closedge[j].lowcost)
{
min = closedge[j].lowcost;
k = j;
}
return k;
}
void MiniSpanTree_PRIM(MGraph G, VertexType u)
{
CLOSEDGE closedge[G.vexnum + 1];
int k, j, i;
k = LocateVex(G, u);
for (j = 0; j < G.vexnum; ++j)
if (j != k)
{
closedge[j].adjvex = u;
closedge[j].lowcost = G.arcs[k][j].adj;
}
closedge[k].lowcost = 0;
for (i = 1; i < G.vexnum; ++i)
{
k = minimum(closedge, G.vexnum);
printf("(%d,%d)\n", closedge[k].adjvex, G.vexs[k]);
closedge[k].lowcost = 0;
for (j = 0; j < G.vexnum; ++j)
{
if (G.arcs[k][j].adj < closedge[j].lowcost)
{
closedge[j].adjvex = G.vexs[k];
closedge[j].lowcost = G.arcs[k][j].adj;
}
}
}
}
int main()
{
MGraph G;
printf("P174 图7.16(a)\n");
CreateUDN(&G);
printf("\n输出生成树上的5条边为:\n");
MiniSpanTree_PRIM(G, 1);
return 0;
}
运行截图
7-4. 将图以邻接表存储,实现Kruskal算法。
code
#include<iostream>
#define Vnum 10
#define MAX 10000
#include<string.h>
#include<algorithm>
using namespace std;
typedef char Datatype;
typedef struct arcnode{
int adjvex;
int weight;
struct arcnode *nextarc;
} arcnode;
typedef struct{
Datatype vexdata;
arcnode *firstarc;
} Adjlist;
typedef struct{
int arcnum, vexnum;
Adjlist adjlist[Vnum];
} GraphTp;
int visit[Vnum];
int quan[Vnum][Vnum];
void creat(GraphTp *g){
int i, j, k, ii, quanz;
char tailarc, headarc;
arcnode *p;
cout << "enter vexnum and arcnum:" << endl;
cin >> g->vexnum >> g->arcnum;
cout << "enter the vexdata:" << endl;
for (i = 0; i < g->vexnum; i++){
cin >> g->adjlist[i].vexdata;
g->adjlist[i].firstarc = NULL;
}
cout << "enter the arcdata:" << endl;
for (ii = 0; ii < g->arcnum; ii++){
cin >> tailarc >> headarc >> quanz;
for (k = 0; k < g->vexnum; k++)
if (g->adjlist[k].vexdata == tailarc){
i = k;
break;
}
for (k = 0; k < g->vexnum; k++)
if (g->adjlist[k].vexdata == headarc){
j = k;
break;
}
p = new arcnode;
p->adjvex = j;
p->weight = quanz;
quan[i][j] = quanz;
quan[j][i] = quanz;
p->nextarc = g->adjlist[i].firstarc;
g->adjlist[i].firstarc = p;
}
}
struct edge{
int weight;
int u, v;
} bian[Vnum];
int cmp(edge A, edge B){
return A.weight < B.weight;
}
void Kruskal(int n, int C[Vnum][Vnum]) {
int i, j;
int nodeset[n];
int count = 0;
bool flag[n];
for (i = 0; i < n; i++) {
nodeset[i] = i;
flag[i] = false;
for (j = 0; j < n; j++)
if (C[i][j] < MAX) {
bian[count].u = i;
bian[count].v = j;
bian[count].weight = C[i][j];
count++;
}
}
sort(bian, bian + count, cmp);
int edgeset = 0;
int w = 0;
count = 0;
while (edgeset < n - 1) {
if (!flag[bian[count].u] && flag[bian[count].v]){
w += bian[count].weight;
flag[bian[count].u] = true;
nodeset[bian[count].u] = nodeset[bian[count].v];
edgeset++;
}
else if (flag[bian[count].u] && !flag[bian[count].v])
{
w += bian[count].weight;
flag[bian[count].v] = true;
nodeset[bian[count].v] = nodeset[bian[count].u];
edgeset++;
}
else if (!flag[bian[count].u] && !flag[bian[count].v])
{
w += bian[count].weight;
flag[bian[count].u] = true;
flag[bian[count].v] = true;
nodeset[bian[count].u] = nodeset[bian[count].v];
edgeset++;
}
else if (nodeset[bian[count].u] != nodeset[bian[count].v])
{
w += bian[count].weight;
edgeset++;
int tmp = nodeset[bian[count].v];
for (i = 0; i < n; i++)
if (nodeset[i] = tmp)
nodeset[i] = nodeset[bian[count].u];
}
count++;
}
cout << "该图权值是:" << w;
}
int main()
{
int i, j;
for (i = 0; i < Vnum; i++)
for (j = 0; j < Vnum; j++)
quan[i][j] = MAX;
GraphTp g;
creat(&g);
cout << endl;
Kruskal(g.vexnum, quan);
return 0;
}
运行截图
7-5.将图以邻接矩阵或邻接表存储,实现Dijkstra算法。
code
#include<bits/stdc++.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
#define MAX_NAME 5
#define MAX_INFO 20
typedef int VRType;
typedef char InfoType;
typedef char VertexType[MAX_NAME];
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20
typedef enum {
DG, DN, AG, AN }GraphKind;
typedef struct{
VRType adj;
InfoType *info;
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
GraphKind kind;
}MGraph;
typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];
int LocateVex(MGraph G, VertexType u){
int i;
for (i = 0; i < G.vexnum; ++i)
if (strcmp(u, G.vexs[i]) == 0)
return i;
return -1;
}
Status CreateDN(MGraph &G){
int i, j, k, w, IncInfo;
char s[MAX_INFO], *info;
VertexType va, vb;
printf("请输入有向网G的顶点数,弧数,弧是否含其它信息(是:1,否:0)(以空格作为间隔): ");
scanf("%d%d%d", &G.vexnum, &G.arcnum, &IncInfo);
printf("请输入%d个顶点的值(<%d个字符):\n", G.vexnum, MAX_NAME);
for (i = 0; i < G.vexnum; ++i)
scanf("%s", G.vexs[i]);
for (i = 0; i < G.vexnum; ++i)
for (j = 0; j < G.vexnum; ++j){
G.arcs[i][j].adj = INFINITY;
G.arcs[i][j].info = NULL;
}
printf("请输入%d条弧的弧尾 弧头 权值(以空格作为间隔): \n", G.arcnum);
for (k = 0; k < G.arcnum; ++k){
scanf("%s%s%d%*c", va, vb, &w);
i = LocateVex(G, va);
j = LocateVex(G, vb);
G.arcs[i][j].adj = w;
if (IncInfo){
printf("请输入该弧的相关信息(<%d个字符): ", MAX_INFO);
gets(s);
w = strlen(s);
if (w){
info = (char*)malloc((w + 1) * sizeof(char));
strcpy(info, s);
G.arcs[i][j].info = info;
}
}
}
G.kind = DN;
return OK;
}
void ShortestPath_DIJ(MGraph G, int v0, PathMatrix &P, ShortPathTable &D){
int v, w, i, j, min;
Status final[MAX_VERTEX_NUM];
for (v = 0; v < G.vexnum; ++v){
final[v] = FALSE;
D[v] = G.arcs[v0][v].adj;
for (w = 0; w < G.vexnum; ++w)
P[v][w] = FALSE;
if (D[v] < INFINITY){
P[v][v0] = TRUE;
P[v][v] = TRUE;
}
}
D[v0] = 0;
final[v0] = TRUE;
for (i = 1; i < G.vexnum; ++i)
{
min = INFINITY;
for (w = 0; w < G.vexnum; ++w)
if (!final[w])
if (D[w] < min){
v = w;
min = D[w];
}
final[v] = TRUE;
for (w = 0; w < G.vexnum; ++w) {
if (!final[w] && min < INFINITY&&G.arcs[v][w].adj < INFINITY && (min + G.arcs[v][w].adj < D[w])){
D[w] = min + G.arcs[v][w].adj;
for (j = 0; j < G.vexnum; ++j)
P[w][j] = P[v][j];
P[w][w] = TRUE;
}
}
}
}
int main(){
int i, j, v0 = 0;
MGraph g;
PathMatrix p;
ShortPathTable d;
CreateDN(g);
ShortestPath_DIJ(g, v0, p, d);
printf("最短路径数组 PathMatrix[i][j] 如下:\n");
for (i = 0; i < g.vexnum; ++i){
for (j = 0; j < g.vexnum; ++j)
printf("%2d", p[i][j]);
printf("\n");
}
printf("%s到各顶点的最短路径长度为:\n", g.vexs[0]);
for (i = 1; i < g.vexnum; ++i)
printf("%s-%s:%d\n", g.vexs[0], g.vexs[i], d[i]);
return 0;
}
运行截图