数据结构学习第十七天

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 }
View Code

//邻接矩阵实现 及 利用 邻接矩阵 实现 广度优先搜索(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 }
View Code

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 }
View Code

(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 }
View Code

猜你喜欢

转载自www.cnblogs.com/57one/p/11443303.html