06-图1 列出连通集 (25 分)

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

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

输出格式:

  • 按照"{ v_1v​1​​ v_2v​2​​ … v_kv​k​​
    }"的格式,每行输出一个连通集。先输出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. C语言
  2. 邻接表方式
  3. 队列
  4. 插入到邻接表时候注意要按大小插入,小在前,大在后
#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值