- 题目来源:
浙江大学在慕课网上开设的《数据结构》课,陈越老师、何钦铭老师主讲,课后作业的一道题。
- 题目描述:
- 思路:
非常基础的一道题,主要考察图的DFS遍历和BFS遍历,最后注意输出的格式就可以了。
- C语言实现:
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MaxVerterNum 100 //最大定点数设为100 #define INFINITY 65535 //无穷设为双字节无符号整数的最大值65535 typedef int WeightType; //边的权值设为int类型 typedef char DataType; //顶点存储的数据类型设置为字符类型 typedef int Vertex; //用顶点下标表示顶点,为整型 bool Visited[MaxVerterNum]; struct QNode { int* Data; //存储元素的数组 int Front; //队列的头指针 int Rear; //队列的尾指针 int MaxSize; //队列的最大容量 }; //创建一个队列 struct QNode* CreateQueue(int MaxSize) { struct QNode* Q = (struct QNode*)malloc(sizeof(struct QNode)); Q->Data = (int *)malloc(MaxSize * sizeof(int)); Q->Front = Q->Rear = 0; Q->MaxSize = MaxSize; return Q; } bool IsFull(struct QNode* Q) { return ((Q->Rear + 1) % Q->MaxSize) == Q->Front; } //在队列尾插入一个元素 //参数 struct QNode* Q 要操作的队列 // int x 待插入的元素 bool AddQ(struct QNode* Q, int x) { if (IsFull(Q)) //判断队列是否为空 { printf("队列满,不能再插入元素\n"); return false; } else { Q->Rear = (Q->Rear + 1) % Q->MaxSize; Q->Data[Q->Rear] = x; return true; } } //判断队列是否为空 bool IsEmpty(struct QNode* Q) { return (Q->Front == Q->Rear); } //在队列头部删除一个元素 int DeleteQ(struct QNode* Q) { if (IsEmpty(Q)) { printf("队列为空\n"); return false; } else { Q->Front = (Q->Front + 1) % Q->MaxSize; return Q->Data[Q->Front]; } } struct GNode { int Nv; //顶点数 int Ne; //边数 WeightType G[MaxVerterNum][MaxVerterNum]; //邻接矩阵 DataType Data[MaxVerterNum][MaxVerterNum]; //存顶点的数据 /*如果顶点无数据,此时Data[]可以不出现*/ }; //描述边的类型 struct ENode { Vertex V1, V2; //有向边<V1,V2> WeightType Weight; //权重 }; //作用:初始化一个有VertexNum个顶点但没有边的图 struct GNode* CreateGraph(int VertexNum) { Vertex V, W; struct GNode* Graph; Graph = (struct GNode*)malloc(sizeof(struct GNode)); //建立图 Graph->Nv = VertexNum; Graph->Ne = 0; //初始化邻接矩阵 for (V = 0;V < Graph->Nv;V++) { for (W = 0;W < Graph->Nv;W++) { Graph->G[V][W] = INFINITY; } } return Graph; } //作用:在图中插入边 void InsertEdge(struct GNode* Graph,struct ENode* E) { ////插入边<V1,V2> //Graph->G[E->V1][E->V2] = E->Weight; ////若是无向图,还需要插入<V2,V1> //Graph->G[E->V2][E->V1] = E->Weight; //插入边<V1,V2> Graph->G[E->V1][E->V2] = 1; //若是无向图,还需要插入<V2,V1> Graph->G[E->V2][E->V1] = 1; } //作用:构建一个图,供主函数调用 struct GNode* BulidGraph() { Vertex V; int NV; struct ENode* E; struct GNode* Graph; scanf("%d",&NV); //读入顶点个数 Graph = CreateGraph(NV); scanf("%d",&(Graph->Ne)); //读入边数 if (Graph->Ne != 0) { E = (struct ENode*)malloc(sizeof(struct ENode)); for (int i = 0;i < Graph->Ne;i++) { ////如果权重不是整型,Weight的读入格式要改 //scanf("%d %d %d",&E->V1,&E->V2,&E->Weight); scanf("%d %d", &E->V1, &E->V2); InsertEdge(Graph,E); } } ////如果顶点有数据的话,读入数据 //for (V = 0;V < Graph->Nv;V++) //{ // scanf("%c",&(Graph->Data[V])); //} return Graph; } void Visit(Vertex V) { printf(" %d",V); } //这个DFS是我自己写的 //void DFS(struct GNode* Graph,Vertex V,void(* Visit)(Vertex)) //{ // Vertex W; // Visit(V); // Visited[V] = true; // // for (W = V + 1; W < Graph->Nv; W++) // { // if (Graph->G[V][W] == 1) // { // if (!Visited[W]) // { // DFS(Graph, W, Visit); // } // } // } //} void DFS(struct GNode* Graph, Vertex V, void(*Visit)(Vertex)) { Vertex j; Visited[V] = true; Visit(V); for (j = 0;j < Graph->Nv;j++) { if (Graph->G[V][j] == 1 && !Visited[j]) { DFS(Graph,j,Visit); } } } void DFSTraverser(struct GNode* Graph) { int i = 0; //初始化所有顶点都是未访问的状态 for (i = 0;i < Graph->Nv;i++) { Visited[i] = false; } for (i=0;i < Graph->Nv;i++) { if (!Visited[i]) { printf("{"); DFS(Graph,i,Visit); printf(" }\n"); } } } bool IsEdge(struct GNode* Graph,Vertex V,Vertex W) { return Graph->G[V][W] < INFINITY ? true : false; } void BFS(struct GNode* Graph, Vertex S, void(*Visit)(Vertex)) { struct QNode* Q; Vertex V, W; Q = CreateQueue(20); Visited[S] = true; Visit(S); AddQ(Q,S); while (!IsEmpty(Q)) { V = DeleteQ(Q); for (W = 0;W < Graph->Nv;W++) { //若W是V的邻接点 并且 没有访问过 if (!Visited[W] && IsEdge(Graph,V,W)) { Visit(W); //访问节点 Visited[W] = true; AddQ(Q,W); } } } } void BFSTraverser(struct GNode* Graph) { int i = 0; //初始化所有顶点都是未访问的状态 for (i = 0; i < Graph->Nv; i++) { Visited[i] = false; } for (i = 0; i < Graph->Nv; i++) { if (!Visited[i]) { printf("{"); BFS(Graph, i, Visit); printf(" }\n"); } } } int main() { struct GNode* Graph = BulidGraph(); // printf("图建立完毕.\n"); DFSTraverser(Graph); BFSTraverser(Graph); // system("pause"); return 0; }