第六章作业(1)

7-1 列出连通集 (30 分)
 

给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:

输入第1行给出2个整数N(0)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

输出格式:

按照"{ v1​​ v2​​ ... vk​​ }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

输入样例:

8 6
0 7
0 1
2 0
4 1
2 4
3 5

输出样例:

{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

根据老师日常引导的方法--我们先从主函数讲起
 1 int main()//首先先从大方向开始掌握思路,于是先打主函数 
 2 {
 3     ALGraph G; //由题知是由图来完成,那么应该先创建一张图 
 4     
 5     createUDG(g) ;// 生成图 
 6      
 7     for(int i=0;i<G.vex;i++) 
 8         sort(G,i);//根据每一个顶点进行排序,从而更好地进行匹配
 9     
10     //排序后进行深搜+广搜
11     
12     //深搜     
13     for(int i=0;i<G.vex;i++)
14     {
15         if(vi[i]==false)//循环输出呐~~ 
16         {
17             cout<<"{";
18             DFS(G,i);
19             cout<<"}"<<endl;
20         }
21     }
22  
23     //转变vi数组 后才能进行广搜
24     for(int i=0;i<Max;i++)
25         vi[i]=false;
26         
27     //开始进行广搜
28     for(int i=0;i<G.vex;i++)
29         {
30             if(vi[i]==false)//此处类似深搜的一段代码,原因就是都是循环输出哒~ 
31             {
32             cout<<"{";
33             BFS(G,i);
34             cout<<"}"<<endl;
35         }
36          } 
37     
38 return 0;
39 }
View Code

 

 

然后就开始一步步补充我们的主函数挖的坑啦~~

 

首先是ALGraph定义

1 typedef struct
2 {//图的定义 
3     int vex, arc;//图的顶点数量和边的数量 
4     adjList vertices;//生成顶点列表  
5 }ALGraph;
View Code

好的,那么我们又给自己挖了一个坑,既然是坑就得补上,AdjList邻接表类型

1 typedef struct VNode{//顶点列表的定义 
2     int data;//留给数据的一个空间 
3     struct ArcNode *firstArc;//这个顶点的第一条边的指针 
4 }VNode,AdjList[Max]; //AdjList表示邻接表类型
View Code

得,又挖了一个坑,但是应该是图的最后一个啦~

1 typedef struct ArcNode{//由顶点列表推出来的边节点定义 
2     int adjvex;//当前结点的顶点位置 
3     struct ArcNode *nextArc;//指向下一条边的指针 
4 }ArcNode,*L;
View Code

 

接着就是生成图的函数啦createUDG(G)~

 1 void createUDG(ALGraph &G)
 2 {
 3     cin >> G.vex >>G.arc;//输入顶点和节点 分别的总数~ 
 4     for(int i=0;i<G.vex;i++)
 5     {
 6         G.vertices[i].data = i;
 7         G.vertices[i].firstArc = NULL;
 8     }
 9     int v1,v2;//一条边的两个顶点 
10     L p1,p2;
11     for(int i=0;i<G.arc;i++)
12     {
13         cin >> v1 >> v2;//对顶点V1处理,将V2加入到链表中
14          p1 = new ArcNode;
15          p1 -> adjvex = v2;
16          p1 -> nextArc = G.vertices[v1].firstArc;
17          G.vertices[v1].firstArc = p1;
18          
19          //        对顶点v2处理,将v1加入到链表中 
20         p2 = new ArcNode;
21         p2 -> adjvex = v1;
22         p2 -> nextArc = G.vertices[v2].firstArc;
23         G.vertices[v2].firstArc = p2;    
24         
25     }
26 }
View Code

 

接着就是排序的--采用冒泡排序。。

 1 void sort(ALGraph G,int v)
 2 {//一种冒泡排序法,对于顶点的边的点进行排序,参考了大佬的排序 
 3     L i,j;
 4     int k;
 5     for(i=G.vertices[v].firstArc;i!=NULL;i=i->nextArc)
 6         for(j=G.vertices[v].firstArc;j->nextArc!=NULL;j=j->nextArc)
 7             if(j->adjvex > j->nextArc->adjvex)
 8             {
 9                 k = j->adjvex;
10                 j->adjvex = j->nextArc->adjvex;
11                 j->nextArc->adjvex = k;
12             }    
13 }
View Code

 

那么接下来就是最后的,额,深搜与广搜了

首先弄一个

//判断是否访问过的数组
bool vi[Max] = {false};

 

接着就是深搜了:

 1 //开始深搜的函数
 2 void(ALGrap G,int v) 
 3  {
 4      //访问当前的结点
 5      cout<<" "<<v;
 6      vi[v] = true;
 7      L p;//与顶点连接的下一个边
 8      
 9      int w;//与顶点连接的下一个点
10      
11      p = G.vertices.firstArc; 
12      while(p!=NULL)
13      {//取得这一条边连接的点,看看是否已经被访问过 
14          w = p->adjvex;
15          if(!vi[w])
16              DFS(G,w);
17         p = p->nextArc; 
18      }
19  }
View Code

接着就是广搜了

 

 1  //广度搜索
 2 void BFS(ALGraph G, int v)
 3 {//队列q,u用作存储出队的元素的下标
 4     queue<int> q;
 5     int u;
 6     //访问顶点
 7     cout<<" "<<v;
 8     vi[v] = true;
 9     //入队
10     q.push(v);
11     while(!=q.empty())
12     {
13         u = q.front();
14         q.pop();
15         
16         //for 循环, 进行出队元素的所有的边的点访问,入队
17         for(L p=G.vertices[u].firstArc; p!=NULL ; p=p->nextArc)
18         {//对于出队的点,判断是否有邻接点,有就访问,然后入队
19             if(!vi[p->adjvex])
20             {
21                 cout<<" "<<p->adjvex;
22                 vi[p->adjvex] = true;
23                 q.push(p->adjvex);
24              } 
25             
26          } 
27      } 
28     
29  } 
View Code

就这样就整个就完成啦~~

可惜就是通不过.........

还是需要修改,格式错误---记录一篇错误的博客。

 下面才是真正的全部代码:

  1 #include<iostream>
  2 #include <queue>
  3 #define Max 20 //最大顶点数
  4 using namespace std;
  5 
  6 
  7 typedef struct ArcNode{//由顶点列表推出来的边节点定义 
  8     int adjvex;//当前结点的顶点位置 
  9     struct ArcNode *nextArc;//指向下一条边的指针 
 10 }ArcNode,*L;
 11 
 12 typedef struct VNode{//顶点列表的定义 
 13     int data;//留给数据的一个空间 
 14     struct ArcNode *firstArc;//这个顶点的第一条边的指针 
 15 }VNode,AdjList[Max]; //AdjList表示邻接表类型
 16 
 17 typedef struct{//图的定义 
 18     int vex, arc;//图的顶点数量和边的数量 
 19     AdjList vertices;//生成顶点列表  
 20 }ALGraph;
 21 
 22 void createUDG(ALGraph &G)
 23 {
 24     cin >> G.vex >>G.arc;//输入顶点和节点 分别的总数~ 
 25     for(int i=0;i<G.vex;i++)
 26     {
 27         G.vertices[i].data = i;
 28         G.vertices[i].firstArc = NULL;
 29     }
 30     int v1,v2;//一条边的两个顶点 
 31     L p1,p2;
 32     for(int i=0;i<G.arc;i++)
 33     {
 34         cin >> v1 >> v2;//对顶点V1处理,将V2加入到链表中
 35          p1 = new ArcNode;
 36          p1 -> adjvex = v2;
 37          p1 -> nextArc = G.vertices[v1].firstArc;
 38          G.vertices[v1].firstArc = p1;
 39          
 40          //        对顶点v2处理,将v1加入到链表中 
 41         p2 = new ArcNode;
 42         p2 -> adjvex = v1;
 43         p2 -> nextArc = G.vertices[v2].firstArc;
 44         G.vertices[v2].firstArc = p2;    
 45         
 46     }
 47 }
 48 
 49 void sort(ALGraph G,int v)
 50 {//一种冒泡排序法,对于顶点的边的点进行排序,参考了大佬的排序 
 51     L i,j;
 52     int k;
 53     for(i=G.vertices[v].firstArc;i!=NULL;i=i->nextArc)
 54         for(j=G.vertices[v].firstArc;j->nextArc!=NULL;j=j->nextArc)
 55             if(j->adjvex > j->nextArc->adjvex)
 56             {
 57                 k = j->adjvex;
 58                 j->adjvex = j->nextArc->adjvex;
 59                 j->nextArc->adjvex = k;
 60             }    
 61 }
 62 
 63 //判断是否访问过的数组 
 64 bool vi[Max] = {false};
 65 
 66 //开始深搜的函数
 67 void DFS(ALGraph G,int v) 
 68  {
 69      //访问当前的结点
 70      cout<<" "<<v;
 71      vi[v] = true;
 72      L p;//与顶点连接的下一个边
 73      
 74      int w;//与顶点连接的下一个点
 75      
 76      p = G.vertices[v].firstArc; 
 77      while(p!=NULL)
 78      {//取得这一条边连接的点,看看是否已经被访问过 
 79          w = p->adjvex;
 80          if(!vi[w])
 81              DFS(G,w);
 82         p = p->nextArc; 
 83      }
 84  }
 85  
 86  //广度搜索
 87 void BFS(ALGraph G, int v)
 88 {//队列q,u用作存储出队的元素的下标
 89     queue<int> q;
 90     int u;
 91     //访问顶点
 92     cout<<" "<< v;
 93     vi[v] = true;
 94     //入队
 95     q.push(v);
 96     while(!q.empty())
 97     {
 98         u = q.front();
 99         q.pop();
100         
101         //for 循环, 进行出队元素的所有的边的点访问,入队
102         for(L p=G.vertices[u].firstArc; p!=NULL ; p=p->nextArc)
103         {//对于出队的点,判断是否有邻接点,有就访问,然后入队
104             if(!vi[p->adjvex])
105             {
106                 cout<<" "<<p->adjvex;
107                 vi[p->adjvex] = true;
108                 q.push(p->adjvex);
109              } 
110             
111          } 
112      } 
113     
114  } 
115  
116 
117 int main()//首先先从大方向开始掌握思路,于是先打主函数 
118 {
119     ALGraph G; //由题知是由图来完成,那么应该先创建一张图 
120     
121     createUDG(G) ;// 生成图 
122      
123     for(int i=0;i<G.vex;i++) 
124         sort(G,i);//根据每一个顶点进行排序,从而更好地进行匹配
125     
126     //排序后进行深搜+广搜
127     
128     //深搜     
129     for(int i=0;i<G.vex;i++)
130     {
131         if(vi[i]==false)//循环输出呐~~ 
132         {
133             cout<<"{";
134             DFS(G,i);
135             cout<<" "<<"}"<<endl;
136         }
137     }
138  
139     //转变vi数组 后才能进行广搜
140     for(int i=0;i<Max;i++)
141         vi[i]=false;
142         
143     //开始进行广搜
144     for(int i=0;i<G.vex;i++)
145         {
146             if(vi[i]==false)//此处类似深搜的一段代码,原因就是都是循环输出哒~ 
147             {
148             cout<<"{";
149             BFS(G,i);
150             cout<<" "<<"}"<<endl;
151         }
152          } 
153     
154 return 0;
155 }
View Code

我真棒!

 
posted @ 2019-05-26 12:13  青梅茶  阅读(193)  评论(0编辑  收藏  举报