题目:给定一个有NN个顶点和EE条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N-1N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
- 输入第1行给出2个整数NN(0<N\le
100<N≤10)和EE,分别是图的顶点数和边数。随后EE行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式:
- 按照"{ v_1v1 v_2v2 … v_kvk
}"的格式,每行输出一个连通集。先输出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 }
关键点:
- C语言
- 邻接表方式
- 队列
- 插入到邻接表时候注意要按大小插入,小在前,大在后
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxVertex 10
typedef int Vertex;
typedef int DataType;
bool Visited[MaxVertex]={false,};
//邻接点
typedef struct AdjVNode* PtrToVNode;
struct AdjVNode{
Vertex AdjV;
PtrToVNode Next;
};
//边
typedef struct ENode* PtrToENode;
struct ENode{
Vertex v,w;
};
typedef PtrToENode Edge;
//表头
typedef struct AdjHead{
PtrToVNode FirstNode;
}AdjList[MaxVertex];
//图
typedef struct GNode * PtrToGNode;
struct GNode{
int numofv;
int numofe;
AdjList adjl;
};
typedef PtrToGNode Graph;
/**
* 建图(无边图)
*/
Graph CreatGraph(int numofvertex){
Graph g = (Graph)malloc(sizeof(struct GNode));
g->numofv = numofvertex;
g->numofe = 0;
for(int v=0;v<g->numofv;v++)
g->adjl[v].FirstNode=NULL;
return g;
}
void InsertEdge(Graph g,Edge e){
PtrToVNode node ,rear;
rear = g->adjl[e->v].FirstNode;
node = (PtrToVNode)malloc(sizeof(struct AdjVNode));
node->AdjV = e->w;
//插入比这次值小的点的前边
if(rear){
if(rear->AdjV<e->w){
while (rear->Next)
{
if(rear->Next->AdjV<e->w) rear=rear->Next;
else break;
}
node->Next = rear->Next;
rear->Next = node;
}else{
node->AdjV = g->adjl[e->v].FirstNode->AdjV;
g->adjl[e->v].FirstNode->AdjV= e->w;
node->Next = g->adjl[e->v].FirstNode->Next;
g->adjl[e->v].FirstNode->Next = node;
}
}else{
node->Next = g->adjl[e->v].FirstNode;
g->adjl[e->v].FirstNode = node;
}
//无向图双向的。
rear = g->adjl[e->w].FirstNode;
node = (PtrToVNode)malloc(sizeof(struct AdjVNode));
node->AdjV = e->v;
if(rear){
if(rear->AdjV<e->v){
while (rear->Next)
{
if(rear->Next->AdjV<e->v) rear=rear->Next;
else break;
}
node->Next = rear->Next;
rear->Next = node;
}else{
node->AdjV = g->adjl[e->w].FirstNode->AdjV;
g->adjl[e->w].FirstNode->AdjV= e->w;
node->Next = g->adjl[e->w].FirstNode->Next;
g->adjl[e->w].FirstNode->Next = node;
}
}else{
node->Next = g->adjl[e->w].FirstNode;
g->adjl[e->w].FirstNode = node;
}
}
void DFS(Graph g,Vertex v){
PtrToVNode w;
printf("%d ",v);
Visited[v]=true;
for (w=g->adjl[v].FirstNode ;w; w=w->Next){
if ( !Visited[w->AdjV] ) /* 若W->AdjV未被访问 */
DFS( g, w->AdjV); /* 则递归访问之 */
}
}
struct Qnode{
int data;
struct Qnode* next;
};
struct queue
{
struct Qnode* front;
struct Qnode* rear;
};
typedef struct queue* Queue;
Queue CreateQueue(){
Queue q;
q = (Queue)malloc(sizeof(struct queue));
q->rear = NULL;
q->front = q->rear;
return q;
}
void AddQ(Queue q,int v){
if(q->rear ==NULL){
struct Qnode* n = (struct Qnode*)malloc(sizeof(struct Qnode));
n->data = v;
n->next = NULL;
q->front =q->rear=n;
return;
}
struct Qnode* newnode = (struct Qnode*)malloc(sizeof(struct Qnode));
newnode->data = v;
newnode->next = NULL;
q->rear->next = newnode;
q ->rear= q->rear->next;
}
bool IsEmpty(Queue q){
if(q->rear ==NULL)return true;
return false;
}
int DeleteQ(Queue q){
struct Qnode* f ;
int ret;
if(q->front==q->rear){//only one node
ret = q->front->data;
q->front = q->rear =NULL;
}else{
ret = q->front->data;
f= q->front;
q->front=f->next;
free(f);
}
return ret;
}
void BFS ( Graph Graph, Vertex v){
Queue Q;
PtrToVNode W;
Vertex x;
Q = CreateQueue(); /* 创建空队列, MaxSize为外部定义的常数 */
printf("%d ",v);
Visited[v] = true; /* 标记S已访问 */
AddQ(Q, v); /* S入队列 */
while ( !IsEmpty(Q) ) {
x = DeleteQ(Q); /* 弹出V */
for( W=Graph->adjl[x].FirstNode; W; W=W->Next ){ /* 对其每隔邻接点W */
if (!Visited[W->AdjV]) {
/* 访问顶点W */
printf("%d ",W->AdjV);
Visited[W->AdjV] = true; /* 标记W已访问 */
AddQ(Q, W->AdjV); /* W入队列 */
}
}
}
}
Graph BuildGraph(){
Graph graph;
int nv;
//获得边数和顶点数
scanf("%d",&nv);
graph = CreatGraph(nv);//建立无边图
scanf("%d",&graph->numofe);
for(int i=0;i<graph->numofe;i++){
Edge e= (Edge)malloc(sizeof(struct ENode));
scanf("%d %d",&e->v,&e->w);
InsertEdge(graph,e);
} //获得边
return graph;
}
int main(){
Graph graph;
graph = BuildGraph();
//DFS遍历输出
for(int i=0;i<graph->numofv;i++){
if(!Visited[i]){
printf("{ ");
DFS(graph,i);
printf("}\n");
}
}
for(int i=0;i<MaxVertex;i++) Visited[i]=false;
//BFS遍历输出
for(int i=0;i<graph->numofv;i++){
if(!Visited[i]){
printf("{ ");
BFS(graph,i);
printf("}\n");
}
}
system("pause");
return 0;
}