图的存储实现

#include<iostream>
#include<iomanip>
using namespace std;

typedef char VerType;
#define MAXNUM 20
// 邻接矩阵的定义 
typedef struct {
    VerType Vers[MAXNUM];  //1 顶点 数组 一维数组
    int Arcs[MAXNUM][MAXNUM];  //2 边 二维数组 邻接矩阵 
    int VerNum;       //3 点数
    int ArcNUm;      //4 边数 
}AMGraph; 
// 在图G的顶点数组中找顶点v的位置 下标
int LocateVer(AMGraph G,VerType v){
    for(int i=0;i<G.VerNum;i++){
        if(G.Vers[i]==v) return i;
    }
}
//创建邻接矩阵
void createGraph(AMGraph &G){
    cin>>G.VerNum>>G.ArcNUm;   //首先,输入点数、边数
    int i,j,k;
    VerType x,y;
    for(i=0;i<G.VerNum;i++) cin>>G.Vers[i];  //第二,输入点的信息
    for(i=0;i<G.VerNum;i++)       //在给邻接矩阵赋值之前,全部元素先清零 
        for(j=0;j<G.VerNum;j++)  
          G.Arcs[i][j]=0;    
    for(k=1;k<=G.ArcNUm;k++){      //第三,输入边的信息
        cin>>x>>y;   //输入边的两个顶点 
        i = LocateVer(G,x);             //在顶点数组中找顶点x的位置 下标 
        j = LocateVer(G,y); 
        G.Arcs[i][j]=G.Arcs[j][i]=1;   //修改邻接矩阵中对应位置的值  无向图 两个位置 
    }

//显示图的邻接矩阵
void printGraph(AMGraph G){
     int i;
    cout<<"顶点数="<<G.VerNum<<" 边数="<<G.ArcNUm<<"邻接矩阵如下:\n";
    for(i=0;i<G.VerNum;i++){
        for(int j=0;j<G.VerNum;j++)  cout<<setw(3)<<G.Arcs[i][j];
        cout<<"\n";
    } 
    cout<<"顶点数组如下:\n";
    for(i=0;i<G.VerNum;i++) cout<<setw(3)<<i;
    cout<<"\n"; 
    for(i=0;i<G.VerNum;i++) cout<<setw(3)<<G.Vers[i];
        cout<<"\n"; 

 int visited[MAXNUM]={0};   //全局  辅助数组 用来标记顶点是否访问过  0 未访问    1 已访问 
 //DFS 依次只能访问到当前连通分量中的顶点   其余不连通的顶点是无法访问的   
 //所以,对于非连通图,需要多次启动DFS 
 void DFS(AMGraph G, int v){     
     cout<<G.Vers[v]<<" ";  visited[v]=1;    //输出顶点v   并做标记 
     for(int w=0;w<G.VerNum;w++){   //扫描邻接矩阵中第v行,找顶点v的邻接点w 
         if(G.Arcs[v][w]==1 && visited[w]==0) //如果顶点w没有被访问 
             DFS(G,w);                      //从w开始,继续深度优先搜索 
     }     
 } 
 
 //遍历所有的顶点 
 void DFSALL(AMGraph G){     
     for(int i=0;i<G.VerNum;i++){
         if( visited[i]==0){  //如果顶点i 没有被访问,从i开始DFS           
           DFS(G,i);     //每次调用DFS,计数器加1            
        }
     } 
 }  
 
 //在遍历的基础上,统计连通分量的个数  并分别显示连通分量中的结点 
 int DFSALL_2(AMGraph G){
     int count=0; 
     for(int i=0;i<G.VerNum;i++){
         if( visited[i]==0){  //如果顶点i 没有被访问,从i开始DFS
           count++;  cout<<"\n\n第"<<count<<"个连通分量结点内容如下:\n"; 
           DFS(G,i);     //每次调用DFS,计数器加1            
        }
     }
     return count; 
 }  
int main(){
    AMGraph G;       //定义邻接矩阵存储的图G 
    createGraph(G);  //创建G 
    printGraph(G);   //显示G 
    cout<<"\n\nDFS的结果:" ;
    //DFS(G,0);    //从顶点0开始深度优先搜索 
    //DFSALL(G);  //遍历图中所有顶点
     
    //利用DFS求图中连通分量的个数
    int r=     DFSALL_2(G); 
    cout<<"\n\n图中有"<<r<<"个连通分量\n"; 
}

/*
//例1 一个连通图 
8 8
abcdefgh
a b
a c
b d
b e
c f
c g
d h
e h

//例2  一个非连通图 
6 4
abcdef
a b
b c
c d
e f
 
*/
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值