邻接矩阵存储无向图

没有进行矩阵压缩

没有遍历算法

仅邻接矩阵存储无向图的基本代码实现

/*
    无向图的基本操作包括:
    
    1. 初始化图:创建一个空的图数据结构,并初始化图的顶点数和边数。
    
    2. 创建图
    
    3. 判断邻接矩阵是否合法 
    
    4. 添加顶点:向图中添加一个新的顶点。
    
    5. 添加边:在图中添加一条连接两个顶点的边。
    
    6. 删除顶点:从图中删除一个指定的顶点,同时删除与该顶点相关联的边。
    
    7. 删除边:从图中删除一条指定的边。
    
    8. 判断顶点是否存在:检查图中是否存在指定的顶点。
    
    9. 判断边是否存在:检查图中是否存在指定的边。
    
    10. 获取顶点的邻居顶点:获取与指定顶点直接相连的顶点集合。
        
    11. 获取顶点的度:计算指定顶点的度,即入度和出度的总和。
    
    12. 打印邻接矩阵
    
    这些基本操作可以帮助我们在图中进行顶点和边的增删查改,以及进行图的遍历和分析。
    具体实现会根据不同的图的表示方式和算法来进行。

*/

#include <stdlib.h>
#include <stdio.h>

#define MaxVertexNum 20

typedef int VertexType; 
typedef int EdgeType;

typedef struct{
    VertexType Vex[MaxVertexNum];                    //存储顶点 
    EdgeType Edge[MaxVertexNum][MaxVertexNum];        //存储边 
    int VexNum;                                        //顶点数 
    int EdgeNum;                                    //边数 
}Graph;

//1.初始化图 
void InitGraph(Graph &G)
{
    int i,j;
    for(i=0;i<MaxVertexNum;i++)
    {
        G.Vex[i]=0;                            //顶点值初始化为0 
        for(j=0;j<MaxVertexNum;j++)            
            G.Edge[i][j]=0;                    //邻接矩阵中的元素初始化为0 
    }
    G.VexNum=0;                                //顶点个数初始化为0 
    G.EdgeNum=0;                            //边数初始化为0 
}

//2.创建图 
bool CreateGraph(Graph &G)
{
    int MaxNum,i,j;
    printf("图的顶点个数为:");
    scanf("%d",&MaxNum);
    if(MaxNum<=0)
        return false;
    G.VexNum=MaxNum;
    
    printf("输入顶点值:\n");
    for(i=0;i<G.VexNum;i++)
        scanf("%d",&G.Vex[i]);    
    
    printf("输入(0/1)到邻接矩阵:\n");
    int count=0;
    for(i=0;i<G.VexNum;i++)
    {
        for(j=0;j<G.VexNum;j++)
        {
            scanf("%d",&G.Edge[i][j]);
            if(G.Edge[i][j]==1)
                count++; 
        }
    }
    G.EdgeNum=count/2;
}

//3.判断邻接矩阵是否合法 
bool isValid(Graph G)
{
    //判断是否为空 
    if(G.VexNum<=0)
    {
        printf("图空\n");
        return false;
    }
    
    //判断对角线元素是否非0 
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Edge[i][i]!=0)
        {
            printf("对角线元素非0\n");
            return false;
        }
    }
    
    //判断矩阵是否对称 
    for(int i=0;i<G.VexNum;i++)
    {
        for(int j=0;j<G.VexNum;j++)
        {
            if(G.Edge[i][j]!=G.Edge[j][i])
            {
                printf("矩阵不对称\n");
                return false;
            }
        }
    }
    
    return true;
}

//4.添加顶点
bool AddVertex(Graph &G,VertexType ver)
{
    if(G.VexNum==MaxVertexNum)
        return false;
    
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Vex[i]==ver)
            return false;
    }
    
    G.Vex[G.VexNum]=ver;
    G.VexNum++;
    
    for(int i=0;i<G.VexNum;i++)            //更新邻接矩阵 
    {
        G.Edge[i][G.VexNum-1]=0;         
        G.Edge[G.VexNum-1][i]=0;    
    } 
    
    return true; 
} 

//5.添加边
bool AddEdge(Graph &G,VertexType ver1,VertexType ver2)//传入的是顶点值 
{
    int v1=-1;
    int v2=-1;
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Vex[i]==ver1)
            v1=i;
        if(G.Vex[i]==ver2)
            v2=i;
        if(v1>=0 && v2>=0)        //提前结束 
            break;    
    }
    if(v1<0 || v2<0)
        return false;                    //顶点不存在 
    
    if(G.Edge[v1][v2]==1)
        return false;                    //边已存在
        
    G.Edge[v1][v2]=1;
    G.Edge[v2][v1]=1;
    G.EdgeNum++;
    
    return true;
} 

//6.删除顶点
bool DeleteVertex(Graph &G,VertexType ver)//传入的是顶点值 
{
    int v=-1;
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Vex[i]==ver)
        {
            v=i;
            break;    
        }
    }
    if(v<0 || v>=G.VexNum)
        return false;
                         
    //删除相应的边
    for(int i=v;i<G.VexNum-1;i++)
    {
        for(int j=0;j<G.VexNum;j++)
        {
            G.Edge[i][j]=G.Edge[i+1][j];
            G.Edge[j][i]=G.Edge[j][i+1];
        }    
    }
            
    //删除顶点 
    for(int i=v;i<G.VexNum-1;i++)
        G.Vex[i]=G.Vex[i+1];
    G.VexNum--;
    
    //更新边数
    int count=0;
    for(int i=0;i<G.VexNum;i++)
        for(int j=0;j<G.VexNum;j++)
            if(G.Edge[i][j]==1 || G.Edge[j][i]==1)
                count++;
    G.EdgeNum=count/2;
    
    return true;
} 

//7.删除边
bool DeleteEdge(Graph &G,VertexType ver1,VertexType ver2)
{
    int v1=-1;
    int v2=-1;
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Vex[i]==ver1)
            v1=i;
        if(G.Vex[i]==ver2)
            v2=i;
        if(v1>=0 && v2>=0)        //提前结束 
            break;    
    }    
    if(v1<0 || v2<0)
        return false;
    
    if(G.Edge[v1][v2]==0)
        return false;
    else
    {
        G.Edge[v1][v2]=0;
        G.Edge[v2][v1]=0;
        G.EdgeNum--;
    }
        
    return true;
} 

//8.判断顶点是否存在
bool ExistVertex(Graph G,VertexType ver)//传入的是顶点值,不是下标 
{
    for(int i=0;i<G.VexNum;i++)
        if(G.Vex[i]==ver)
            return true;        
    return false;
}

//9.判断边是否存在 
bool ExistEdge(Graph G,VertexType ver1,VertexType ver2)//传入的是顶点值,不是下标 
{
    int v1,v2;
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Vex[i]==ver1)
            v1=i;
        if(G.Vex[i]==ver2)
            v2=i;    
        if(v1>=0 && v2>=0)        //提前结束 
            break;    
    } 
    if(G.Edge[v1][v2]==0)
        return false;
    return true;
}

//10.获取顶点的邻居顶点
bool GetNeiborVertex(Graph G,VertexType ver)
{
    int v=-1;
    for(int i=0;i<G.VexNum;i++)
    {
         if(G.Vex[i]==ver)
         {
            v=i;
             break; 
        }
    }
    if(v==-1)
    {
        printf("顶点不存在\n");
        return false;
    }
    
    printf("%d的邻居顶点为:",ver);
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Edge[v][i]==1)
            printf("%d ",G.Vex[i]);
    }
    
    return true;
} 

//11.获取顶点的度
int GetDegree(Graph G,VertexType ver)        //注意v是数组下标 
{
    int v=-1;
    int degree=0;
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Vex[i]==ver)
        {
            v=i;
            break;
        }
    }
    
    for(int i=0;i<G.VexNum;i++)
    {
        if(G.Edge[v][i]==1)
            degree++;
    }
    
    return degree;
} 

//12.打印邻接矩阵 
void DisplayGraph(Graph G)
{
    int i,j;
    printf("顶点结点:\n");
    for(i=0;i<G.VexNum;i++)
    {
        printf("%d  ",G.Vex[i]);
    }
    printf("\n");
    
    printf("邻接矩阵:\n");
    for(i=0;i<G.VexNum;i++)
    {
        for(j=0;j<G.VexNum;j++)
        {
            printf("%d  ",G.Edge[i][j]);
            if(j==G.VexNum-1)
            printf("\n");
        }
    }
    /*
    for(int i=0;i<G.VexNum;i++)
    {
        for(int j=0;j<G.VexNum;j++)
        {
            if(G.Edge[i][j]==1 || G.Edge[j][i]==1)
                G.EdgeNum++;
        }
    }
    */
    printf("图的边数为:%d\n",G.EdgeNum);
}


int main()
{
    Graph G;
    InitGraph(G);
    CreateGraph(G);
    
    if(isValid(G)) 
    {
        DisplayGraph(G);
    //    printf("顶点1的度为%d\n",GetDegree(G,1));
    }
    
//    DeleteVertex(G,1);
//    DisplayGraph(G);

//    DeleteEdge(G,1,2);
//    DisplayGraph(G);


    AddVertex(G,5);
    DisplayGraph(G);

    AddEdge(G,5,1);
    AddEdge(G,5,2);
    AddEdge(G,5,3);
    AddEdge(G,5,4);
    DisplayGraph(G);    

/*
    if(ExistVertex(G,2))
        printf("顶点存在\n"); 
    else
        printf("顶点不存在\n");
    if(ExistEdge(G,2,3))
        printf("边存在\n");
    else
        printf("边不存在\n");
*/
//    GetNeiborVertex(G,2);

    return 0;
}

posted on 2023-08-29 11:35  四马路弗洛伊德  阅读(199)  评论(0)    收藏  举报

导航