数据结构与算法——7-6 列出连通集 (25分)

7-6 列出连通集 (25分)

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

输入格式:

输入第1行给出2个整数N(0

输出格式:

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

思路:首先建图,这里采用邻接矩阵来存储图,并将其初始化,如果有边就定义为1,建好表之后,再来了解深度优先搜索和广度优先搜索
深度优先搜索(DFS):
他从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到
一般用堆数据结构来辅助实现DFS算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。
直接贴代码

void DFS(MGraph G,int i)
{
	int j;
	visited[i]=TRUE;
	printf("%c",G.vexs[i]);
	for(j=0;j<numVertexes;j++)
		if(G.arc[i][j]==1&!visited[j])
			DFS(G,j);
}
/*邻接矩阵的深度遍历操作*/
void DFSTraverse( MGraph G ){
    int i;
    for(i=0; i<G.numVetexes; i++)
        visited[i]= FALSE;
    for(i=0; i<G.numVetexes; i++)
        if(!visited[i]){     /*对未访问的顶点调用DFS,若是连通图,只会执行一次 */
            DFS(G,i);
        }
}

然后是广度优先搜素(BFS):
类似于树的层序遍历,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。如果所有节点均被访问,则算法中止。一般用队列数据结构来辅助实现BFS算法。
数据结构与算法——7-6 列出连通集 (25分)_第1张图片

/*邻接矩阵的广度遍历操作*/
void BFSTraverse( MGraph G){
    int i,j;
    int temp_i;//暂存i的值,为了不忘i的初心,因为后面的语句会改变i的值
    Queue Q;
    for( i=0; i<G.numVetexes;i++)
        visited[i]=FALSE;
    InitQueue(&Q);    /*初始化队列*/
    for( i=0; i<G.numVetexes; i++){     /*对每一个顶点做循环*/
        temp_i=i;
        if(!visited[i]){
            visited[i]=TRUE;    /*设置当前结点访问过*/

           // printf("{ ");
            printf("%d ",G.vexs[i]);
            EnQueue(&Q,i);      /*将此顶点入队列*/

            while( !QueueEmpty(Q) )/*队列中仍有元素*/
            {

                DeQueue(&Q,&i);//将队中元素出队列,赋值给i
                /*判断其他顶点若与当前顶点存在边且未访问*/
                for(j=0;j<G.numVetexes;j++){
                    if(G.arc[i][j] == 1&&!visited[j]){
                        visited[j]=TRUE;//标记为已访问
                        printf("%d ",G.vexs[j]);//打印顶点
                        EnQueue(&Q,j);//将找到的顶点入列
                    }
                }
            }
           // printf("}\n");
        }
        i=temp_i;   //恢复i的值
    }
}
#include 
#include 

typedef int VertexType;
typedef int EdgeType;
#define MAXVEX 100
#define INFINITY 65535              //用双字节的35535来表示无穷大
typedef int Boolean;
Boolean visited[MAXVEX];               //访问标志的数组

#define TRUE 1
#define FALSE 0
#define ERROR -1

#define MAXSIZE 100
typedef struct{
    int data[MAXSIZE];
    int front;
    int rear;
}Queue;


typedef struct {
    VertexType vexs[MAXVEX];        //顶点表
    EdgeType arc[MAXVEX][MAXVEX];   //邻接矩阵,可看作边表
    int numVetexes,numEdges;        //图中当前的顶点数和边数
}MGraph;

/*初始化队列*/
void InitQueue(Queue *Q){
    Q->front=0;
    Q->rear=0;
}
/*入队列*/
void EnQueue(Queue *Q,int e){
    if( (Q->rear+1)%MAXSIZE ==Q->front)  /*判断队满*/
        return ;
    Q->data[Q->rear]=e;
    Q->rear=(Q->rear+1)%MAXSIZE;
}

/*出队列*/
void DeQueue(Queue *Q,int *e){
    if(Q->front ==Q->rear)//判断队空
        return ;
    *e = Q->data[Q->front];
    Q->front=(Q->front+1)%MAXSIZE;

}

int QueueEmpty(Queue Q){
    if(Q.front ==Q.rear)
        return 1;
    else
        return 0;

}

void CreateMGraph( MGraph *G ){
    int i,j,k,w;
    //printf("输入顶点数和边数:\n");
    scanf("%d %d",&G->numVetexes,&G->numEdges);
    for( i=0;i<G->numVetexes;i++){
        G->vexs[i] = i;
        for(j=0;j<G->numVetexes;j++)
            G->arc[i][j]=INFINITY;
    }
    for( k=0;k<G->numEdges;k++){
        scanf("%d %d",&i,&j);//输入顶点V1和V2的下标
        G->arc[i][j]=1;//默认所有边的权值都为1
        G->arc[j][i]=1;
    }
}

/*邻接矩阵的深度优先递归算法*/
void DFS(MGraph G,int i){
    int j;
    visited[i] = TRUE;
    printf("%d ",G.vexs[i]);//打印顶点
    for( j=0; j<G.numVetexes; j++)
        if(G.arc[i][j]== 1 && !visited[j] )
            DFS( G, j );
}

/*邻接矩阵的深度遍历操作*/
void DFSTraverse( MGraph G ){
    int i;
    for(i=0; i<G.numVetexes; i++)
        visited[i]= FALSE;
    for(i=0; i<G.numVetexes; i++)
        if(!visited[i]){     /*对未访问的顶点调用DFS,若是连通图,只会执行一次 */
            printf("{ ");
            DFS(G,i);
            printf("}\n");
        }
}

/*邻接矩阵的广度遍历操作*/
void BFSTraverse( MGraph G){
    int i,j;
    int temp_i;//暂存i的值,因为后面的语句会改变i的值
    Queue Q;
    for( i=0; i<G.numVetexes;i++)
        visited[i]=FALSE;
    InitQueue(&Q);    /*初始化队列*/
    for( i=0; i<G.numVetexes; i++){     /*对每一个顶点做循环*/
        temp_i=i;
        if(!visited[i]){
            visited[i]=TRUE;    /*访问*/

            printf("{ ");
            printf("%d ",G.vexs[i]);
            EnQueue(&Q,i);      /*将此顶点入队列*/

            while( !QueueEmpty(Q) )/*队列中仍有元素*/
            {

                DeQueue(&Q,&i);
                for(j=0;j<G.numVetexes;j++){
                    if(G.arc[i][j] == 1&&!visited[j]){
                        visited[j]=TRUE;
                        printf("%d ",G.vexs[j]);
                        EnQueue(&Q,j);
                    }
                }
            }
            printf("}\n");
        }
        i=temp_i;   //恢复i的值
    }
}

int main()
{
    MGraph G;
    CreateMGraph(&G);
    DFSTraverse(G);
    BFSTraverse(G);
    return 0;
}

你可能感兴趣的:(数据结构与算法,队列,算法,数据结构,DFS,BFS)