14:39:22 2019-09-01
学习
图的两种遍历方法:
①DFS 深度优先搜索(Depth First Search)
②BFS 广度优先搜索(Breadth First Search) //利用队列实现广度优先
//邻接表实现 及 利用 邻接表 实现 深度优先搜索(DFS)

1 #define _CRT_SECURE_NO_WARNINGS
2 #include<stdio.h>
3 #include<malloc.h>
4 //表示图的两种方法
5 //邻接矩阵 G[N][N] N个顶点从0到N-1编号
6 //邻接表 表示
7 /*Graph Create(); //建立并返回空图
8 Graph InsertVertex(Graph G, Vertex v); //将v插入G
9 Graph InsertEdge(Graph G, Edge e); //将e插入G
10 void DFS(Graph G, Vertex v); //从顶点v出发深度优先遍历图G
11 void BFS(Graph G, Vertex v); //从顶点v出发宽度优先遍历图G
12 void ShortestPath(Graph G, Vertex v, int Dist[]); //计算图G中顶点v到任意其它顶点的最短距离
13 void MST(Graph G); //计算图G的最小生成树*/
14
15 //图的邻接表表示法
16 #define MaxVerterNum 100 //最大顶点数
17 #define INFINITY 65535 //
18 typedef int Vertex; //顶点下标表示顶点
19 typedef int WeightType; //边的权值
20 typedef char DataType; //顶点存储的数据类型
21
22 //边的定义
23 typedef struct ENode* PtrToENode;
24 typedef PtrToENode Edge;
25 struct ENode
26 {
27 Vertex V1, V2; //有向边<V1,V2>
28 WeightType Weight; //权重
29 };
30
31 //邻接点的定义
32 typedef struct AdjVNode* PtrToAdjVNode;
33 struct AdjVNode
34 {
35 Vertex AdjV; //邻接点下标
36 WeightType Weight; //边权重
37 PtrToAdjVNode Next; //指向下一个邻接点的指针
38 };
39
40 //顶点表头节点的定义
41 typedef struct Vnode
42 {
43 PtrToAdjVNode FirstEdge; //边表头指针
44 DataType Data; //存顶点的数据
45 }AdjList[MaxVerterNum]; //AdjList是邻接表类型
46
47 //图节点的定义
48 typedef struct GNode* PtrToGNode;
49 typedef PtrToGNode LGraph;
50 struct GNode
51 {
52 int Nv; //顶点数
53 int Ne; //边数
54 AdjList G; //邻接表
55 };
56
57 LGraph CreateGraph(int VertexNum)
58 {//初始化一个有VertexNum个顶点但没有边的图
59 Vertex V;
60 LGraph Graph;
61
62 Graph = (LGraph)malloc(sizeof(struct GNode)); //建立图
63 Graph->Nv = VertexNum;
64 Graph->Ne = 0;
65 //初始化邻接表头指针
66 for (V = 0; V < Graph->Nv; V++)
67 Graph->G[V].FirstEdge = NULL;
68 return Graph;
69 }
70
71 void InsertEdge(LGraph Graph, Edge E)
72 {
73 PtrToAdjVNode NewNode;
74 //插入边<V1,V2>
75 NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
76 NewNode->AdjV = E->V2;
77 NewNode->Weight = E->Weight;
78 NewNode->Next = Graph->G[E->V1].FirstEdge;
79 Graph->G[E->V1].FirstEdge = NewNode;
80
81 //若是无向图 还要插入边<V2,V1>
82 NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
83 NewNode->AdjV = E->V1;
84 NewNode->Weight = E->Weight;
85 NewNode->Next = Graph->G[E->V2].FirstEdge;
86 Graph->G[E->V2].FirstEdge = NewNode;
87 }
88
89 LGraph BuildGraph()
90 {
91 LGraph Graph;
92 Edge E;
93 Vertex V;
94 int Nv, i;
95
96 scanf("%d", &Nv); /* 读入顶点个数 */
97 Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */
98 scanf("%d", &(Graph->Ne)); //读入边数
99 if (Graph->Ne != 0)
100 {
101 E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */
102 /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */
103 for (i = 0; i < Graph->Ne; i++)
104 {
105 scanf("%d %d %d", &E->V1, &E->V2, &E->Weight);
106 InsertEdge(Graph, E);
107 }
108 }
109 /* 如果顶点有数据的话,读入数据 */
110 for (V = 0; V < Graph->Nv; V++)
111 scanf(" %c", &(Graph->G[V].Data));
112 return Graph;
113 }
114
115 //DFS 利用邻接表存储的图 实现 深度优先搜索
116 int visited[100];
117 void Visit(Vertex V)
118 {
119 printf("访问顶点%d\n", V);
120 }
121
122 // visited[]是全局变量 初始化为0
123 void DFS(LGraph Graph, Vertex V) //以V为出发点访对邻接表存储的图进行DFS访问
124 {
125 Visit(V);
126 visited[V] = 1;
127
128 PtrToAdjVNode W; //用来从某个点 出发访问
129 for (W = Graph->G[V].FirstEdge; W; W = W->Next)
130 {
131 if (!visited[W->AdjV]) //若 W->Adjv未被访问 则递归访问
132 DFS(Graph, W->AdjV);
133 }
134 }
//邻接矩阵实现 及 利用 邻接矩阵 实现 广度优先搜索(BFS)

1 #define _CRT_SECURE_NO_WARNINGS
2 #include<stdio.h>
3 #include<malloc.h>
4 //表示图的两种方法
5 //邻接矩阵 G[N][N] N个顶点从0到N-1编号
6 //邻接表 表示
7 /*Graph Create(); //建立并返回空图
8 Graph InsertVertex(Graph G, Vertex v); //将v插入G
9 Graph InsertEdge(Graph G, Edge e); //将e插入G
10 void DFS(Graph G, Vertex v); //从顶点v出发深度优先遍历图G
11 void BFS(Graph G, Vertex v); //从顶点v出发宽度优先遍历图G
12 void ShortestPath(Graph G, Vertex v, int Dist[]); //计算图G中顶点v到任意其它顶点的最短距离
13 void MST(Graph G); //计算图G的最小生成树*/
14
15 //图的邻接矩阵表示法
16 #define MaxVerterNum 100 //最大顶点数
17 #define INFINITY 65535 //
18 typedef int Vertex; //顶点下标表示顶点
19 typedef int WeightType; //边的权值
20 typedef char DataType; //顶点存储的数据类型
21
22 //边的定义
23 typedef struct ENode* PtrToENode;
24 typedef PtrToENode Edge;
25 struct ENode
26 {
27 Vertex V1, V2; //有向边<V1,V2>
28 WeightType Weight; //权重
29 };
30
31 //图节点的定义
32 typedef struct GNode* PtrToGNode;
33 typedef PtrToGNode MGraph; //以邻接矩阵存储的图类型
34 struct GNode
35 {
36 int Nv; //顶点数
37 int Ne; //边数
38 WeightType G[MaxVerterNum][MaxVerterNum]; //邻接矩阵
39 DataType Data[MaxVerterNum]; //存顶点的数据
40 };
41
42 MGraph CreateGraph(int VertexNum)
43 {//初始化一个有VerterNum个顶点但没有边的图
44 Vertex V, W;
45 MGraph Graph;
46
47 Graph = (MGraph)malloc(sizeof(struct GNode)); //建立图
48 Graph->Nv = VertexNum;
49 Graph->Ne = 0;
50 //初始化邻接矩阵
51 for (V = 0; V < Graph->Nv; V++)
52 for (W = 0; W < Graph->Nv; W++)
53 Graph->G[V][W] = INFINITY;
54 return Graph;
55 }
56
57 void InsertEdge(MGraph Graph, Edge E)
58 {
59 //插入边<V1,V2>
60 Graph->G[E->V1][E->V2] = E->Weight;
61 //如果是无向图 还要插入边<V2,V1>
62 Graph->G[E->V2][E->V1] = E->Weight;
63 }
64
65 MGraph BuildGraph()
66 {
67 MGraph Graph;
68 Edge E;
69 Vertex V;
70 int Nv, i;
71
72 scanf("%d", &Nv); //读入顶点个数
73 Graph = CreateGraph(Nv); //初始化有Nv个顶点但没有边的图
74
75 scanf("%d", &(Graph->Ne)); //读入边数
76 if (Graph->Ne != 0) //如果有边
77 {
78 E = (Edge)malloc(sizeof(struct ENode)); //建立边节点
79 //读入边 格式为 起点 终点 权重 插入邻接矩阵
80 for (int i = 0; i < Graph->Ne; i++)
81 {
82 scanf("%d %d %d", &(E->V1), &(E->V2), &(E->Weight));
83 InsertEdge(Graph, E);
84 }
85 }
86 //若顶点有数据 读入数据
87 for (V = 0; V < Graph->Nv; V++)
88 scanf("%c", &(Graph->Data[V]));
89 return Graph;
90 }
91
92 //邻接矩阵 实现广度优先搜索 BFS 利用队列
93 #define Size 50
94 int Queue[Size];
95 int Front=1;
96 int Rear=0;
97 int size;
98
99 int Succ(int Value)
100 {
101 if (Value < Size)
102 return Value;
103 else
104 return 0;
105 }
106
107 int IsEmpty()
108 {
109 return (size == 0) ? 1 : 0;
110 }
111 int IsFull()
112 {
113 return (size == Size) ? 1 : 0;
114 }
115 void EnQueue(int Element)
116 {
117 Rear = Succ(Rear+1);
118 Queue[Rear] = Element;
119 size++;
120 }
121 int DeQueue()
122 {
123 int Element = Queue[Front];
124 Front = Succ(Front+1);
125 size--;
126 return Element;
127 }
128
129 //利用队列 与树的层序遍历相似
130 int visited[50];
131 int IsEdge(MGraph Graph, int V, int W) //IsEdge 检查<V,W>是否是图Graph中的一条边
132 {
133 return (Graph->G[V][W] < INFINITY) ? 1 : 0;
134 }
135 void Visit(Vertex V)
136 {
137 printf("访问节点%d\n", V);
138 }
139 void BFS(MGraph Graph, Vertex S) //从节点S出发对以邻接矩阵存储的图Graph进行BFS搜索
140 {
141 EnQueue(S);
142 Visit(S);
143 visited[S] = 1;
144
145 while (!IsEmpty())
146 {
147 Vertex V=DeQueue();
148 for (int W = 0; W < Graph->Nv; W++)
149 if (!visited[W] && IsEdge(Graph, V, W))
150 {
151 EnQueue(W);
152 Visit(W);
153 visited[W] = 1;
154 }
155 }
156 }
PTA第15题 利用 邻接矩阵实现 图 并 用 深度优先搜索(DFS) 和 广度优先搜索(BFS) 输出数据

1 #define _CRT_SECURE_NO_WARNINGS
2 #include<stdio.h>
3 #include<malloc.h>
4 #define True 1
5 #define False 0
6 typedef struct ENode* Edge;
7 struct ENode
8 {
9 int V1, V2;
10 };
11
12 typedef struct Graph* MGraph;
13 struct Graph
14 {
15 int Nv;
16 int Ne;
17 int G[10][10];
18 };
19
20 MGraph CreateGraph(int MaxVertex) //初始化一个没有边的图
21 {
22 MGraph Graph = (MGraph)malloc(sizeof(struct Graph));
23 Graph->Nv = MaxVertex;
24 Graph->Ne = 0;
25 for (int i = 0; i < Graph->Nv; i++)
26 for (int j = 0; j < Graph->Nv; j++)
27 Graph->G[i][j] =False;
28 return Graph;
29 }
30
31 void Insert(MGraph Graph, Edge E)
32 { //插入一个无向图
33 Graph->G[E->V1][E->V2] = 1;
34 Graph->G[E->V2][E->V1] = 1;
35 }
36
37 MGraph BuildGraph()
38 {
39 MGraph Graph;
40 Edge E;
41 int V;
42 int Nv;
43 scanf("%d", &Nv);
44 Graph = CreateGraph(Nv);
45 scanf("%d\n", &(Graph->Ne));
46 if (Graph->Ne)
47 {
48 E = (Edge)malloc((sizeof(struct ENode)));
49 for (int i = 0; i < Graph->Ne; i++)
50 {
51 scanf("%d %d\n", &(E->V1), &(E->V2));
52 Insert(Graph, E);
53 }
54 }
55 return Graph;
56 }
57 //DFS 深度优先遍历
58 int visited1[11];
59 int IsEdge(MGraph Graph,int V, int W)
60 {
61 return (Graph->G[V][W]==True)? 1 : 0;
62 }
63 void Visit(int V)
64 {
65 printf("%d ", V);
66 }
67 void DFS(MGraph Graph, int V) //默认从编号最小的点出发 即从V=0出发
68 {
69 Visit(V);
70 visited1[V] = 1;
71 for (int i = 0; i < Graph->Nv; i++)
72 {
73 if (!visited1[i] && IsEdge(Graph, V, i))
74 DFS(Graph, i);
75 }
76 }
77 void ListComponetsForDFS(MGraph Graph) //解决图不连通的问题
78 {
79 for (int i = 0; i < Graph->Nv; i++)
80 {
81 if (!visited1[i])
82 {
83 printf("{ ");
84 DFS(Graph, i);
85 printf("}\n");
86 }
87 }
88 }
89
90 //BFS 广度优先遍历
91 #define Size 11
92 int visited2[11];
93 int Queue[11];
94 int Front = 1;
95 int Rear = 0;
96 int size = 0;
97 int IsEmpty()
98 {
99 return (size == 0) ? 1 : 0;
100 }
101 int Succ(int Value)
102 {
103 if (Value < Size)
104 return Value;
105 else
106 return 0;
107 }
108 void EnQueue(int V)
109 {
110 Rear = Succ(Rear + 1);
111 Queue[Rear] = V;
112 size++;
113 }
114 int DeQueue()
115 {
116 int V = Queue[Front];
117 Front = Succ(Front + 1);
118 size--;
119 return V;
120 }
121 void BFS(MGraph Graph, int V)
122 {
123 EnQueue(V);
124 Visit(V);
125 visited2[V] = 1;
126 while (!IsEmpty())
127 {
128 int W=DeQueue();
129 for (int i = 0; i < Graph->Nv; i++)
130 {
131 if (!visited2[i] && IsEdge(Graph, W, i))
132 {
133 EnQueue(i);
134 Visit(i);
135 visited2[i] = 1;
136 }
137 }
138 }
139 }
140 void ListComponetsForBFS(MGraph Graph)
141 {
142 for (int i = 0; i < Graph->Nv; i++)
143 {
144 if (!visited2[i])
145 {
146 printf("{ ");
147 BFS(Graph, i);
148 printf("}\n");
149 }
150 }
151 }
152 int main()
153 {
154 MGraph Graph = BuildGraph();
155 ListComponetsForDFS(Graph);
156 ListComponetsForBFS(Graph);
157 return 0;
158 }
(os:稍微吐槽一句 我现在才认识什么是深度优先搜索和广度优先搜索 上学期就学的人是大佬)
PTA第16题 007逃生问题 其实也是建图 然后利用图的 深度优先搜索(DFS) 当然广度优先搜索也可以
要计算节点之间的路径 我是新建了一个 存坐标的结构体 利用 元素在图里下标 和在 结构体下标一样 来进行计算
(os:最后找了快一小时bug 最后发现是因为我对递归的理解不过关 以后要抽空写写递归)

1 #define _CRT_SECURE_NO_WARNINGS
2 #include<stdio.h>
3 #include<malloc.h>
4 #include<math.h>
5 #define True 1
6 #define False 0
7 #define SizeOfPosition 100
8 float Length; //跳跃长度
9 struct Position
10 {
11 int x;
12 int y;
13 }Positions[SizeOfPosition];
14
15 float Distance(float x1, float y1, float x2, float y2)
16 {
17 return sqrt(((y2 - y1) * (y2 - y1)) + ((x2 - x1) * (x2 - x1)));
18 }
19
20 typedef struct ENode* Edge;
21 struct ENode
22 {
23 int V1;
24 int V2;
25 };
26
27 typedef struct Graph* MGraph;
28 struct Graph
29 {
30 int Nv;
31 int Ne;
32 int G[100][100];
33 };
34
35 MGraph CreateGraph(int MaxVertex)
36 {
37 MGraph Graph = (MGraph)malloc(sizeof(struct Graph));
38 Graph->Nv = MaxVertex;
39 Graph->Ne = 0;
40 for (int i = 0; i < Graph->Nv; i++)
41 for (int j = 0; j < Graph->Nv; j++)
42 Graph->G[i][j] = 0;
43 return Graph;
44 }
45
46 void Insert(MGraph Graph, Edge E)
47 {
48 Graph->G[E->V1][E->V2] = 1;
49 Graph->G[E->V2][E->V1] = 1;
50 }
51
52 MGraph BuildGraph()
53 {
54 MGraph Graph;
55 Edge E;
56 int Nv;
57 scanf("%d %f\n", &Nv, &Length);
58 Graph = CreateGraph(Nv);
59 for (int i = 0; i < Graph->Nv; i++)
60 {
61 int x, y;
62 scanf("%d %d\n", &x, &y);
63 Positions[i].x = x;
64 Positions[i].y = y;
65 }
66 for(int i=0;i<Graph->Nv;i++)
67 for (int j =i+1; j < Graph->Nv; j++)
68 {
69 float dis = Distance(Positions[i].x, Positions[i].y, Positions[j].x, Positions[j].y);
70 if (dis <=Length)
71 {
72 E = (Edge)malloc(sizeof(struct ENode));
73 E->V1 = i;
74 E->V2 = j;
75 Insert(Graph, E);
76 }
77 }
78 return Graph;
79 }
80 int visited[100];
81 int IsEdge(MGraph Graph,int V,int W)
82 {
83 return (Graph->G[V][W] == 1) ? 1 : 0;
84 }
85 int Judget(MGraph Graph,int V,float Length) //深度优先遍历
86 {
87 visited[V] = 1;
88 if (Distance(0, 50, Positions[V].x, Positions[V].y) <= Length|| Distance(0, -50, Positions[V].x, Positions[V].y) <= Length
89 || Distance(50,0, Positions[V].x, Positions[V].y) <= Length || Distance(-50, 0, Positions[V].x, Positions[V].y) <= Length)
90 return 1;
91 for (int i = 0; i < Graph->Nv; i++)
92 {
93 if (!visited[i] && IsEdge(Graph, V, i))
94 if (Judget(Graph, i, Length))
95 return 1;
96 }
97 return 0;
98 }
99 int ListComponets(MGraph Graph)
100 {
101 for (int i = 0; i < Graph->Nv; i++)
102 {
103 if (!visited[i] && (Length+7.5)>=Distance(0, 0, Positions[i].x, Positions[i].y))
104 if (Judget(Graph, i, Length))
105 return 1;
106 }
107 return 0;
108 }
109 int main()
110 {
111 MGraph Graph;
112 Graph = BuildGraph();
113 if (ListComponets(Graph))
114 printf("Yes");
115 else
116 printf("No");
117 return 0;
118 }
