数据结构 实验五1) 采用邻接矩阵/邻接表建立图(无向图,有向图,无向网络,有向网络); 2) 采用深度优先/广度优先搜索方式遍历图;

实验目的:

      1. 掌握图的邻接矩阵和邻接表的存储结构;

      2. 验证图在不同存储结构下遍历操作的实现。

      3. 掌握图的实际应用

实验内容:

采用邻接矩阵/邻接表建立图无向图,有向图,无向网络,有向网络);   

采用深度优先/广度优先搜索方式遍历图

 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <LIMITS.H>

using namespace std;

#define Status int
#define VRType int
#define InfoType char
#define VertexType char

#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0

#define INFINITY 0 //最大值
#define MAX_VERTEX_NUM 20 //最大顶点个数


bool visited[MAX_VERTEX_NUM];//访问标志数组

typedef struct ArcCell//邻接矩阵(元素)类型
{
    VRType adj; //顶点关系(边或弧),图用1\0表示是否相邻,网为权值
    InfoType *info; //边或弧的相关信息指针
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct//图的邻接矩阵类型
{
    VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
    AdjMatrix arcs; //邻接矩阵
    int vexnum,arcnum; //图的顶点数和边或弧数
} Mgraph;

void (*VisitFunc)(Mgraph G,int v);//函数变量

void Input(InfoType *info)//录入弧
{
    info=(char*)malloc(sizeof(char));
    scanf("%c",&*info);
}

Status LocateVex(Mgraph &G,VertexType u)//若G中存在点u,则返回该点在图中的位置
{
    int Loc;
    for(Loc=0; Loc<G.vexnum; Loc++)
    {
        if(G.vexs[Loc]==u)
        {
            return Loc;
        }
    }
    return -1;
}

Status CreateDG(Mgraph &G)//采用邻接矩阵表示法,构造有向图G
{
    int IncInfo,i,j,k;
    char v1,v2;
    printf("请输入图的顶点数(1~20):\n");
    scanf("%d",&G.vexnum);
    getchar();
    printf("请输入图的弧数:\n");
    scanf("%d",&G.arcnum);
    getchar();
    printf("各弧是否含有其他信息(1(有),0(没有)):\n");
    scanf("%d",&IncInfo);
    getchar();
    for(i=0; i<G.vexnum; i++)
    {
        printf("请输入第%d个顶点:\n",i+1);
        scanf("%c",&G.vexs[i]);
        getchar();
    }
    for(i=0; i<G.vexnum; i++)
    {
        for(j=0; j<G.vexnum; j++)
        {
            G.arcs[i][j].adj=INFINITY;
            G.arcs[i][j].info=NULL;
        }
    }
    for(k=0; k<G.arcnum; k++)
    {
        printf("请输入一条弧连接的顶点:\n");
        printf("弧尾顶点:\n");//输入一条弧依附的顶点
        scanf("%c",&v1);
        getchar();
        printf("弧头顶点:\n");
        scanf("%c",&v2);
        getchar();
        i=LocateVex(G,v1);
        j=LocateVex(G,v2);//确定v1和v2在G中的位置
        G.arcs[i][j].adj=1;//v1和v2的连接关系
        if(IncInfo)
        {
            Input(G.arcs[i][j].info);//若弧含有相关信息,则输入
        }
    }
    return OK;
}//CreateDG

Status CreateDN(Mgraph &G)//采用邻接矩阵表示法,构造有向网G
{
    int IncInfo,i,j,k,w;
    char v1,v2;
    printf("请输入图的顶点数(1~20):\n");
    scanf("%d",&G.vexnum);
    getchar();
    printf("请输入图的弧数:\n");
    scanf("%d",&G.arcnum);
    getchar();
    printf("各弧是否含有其他信息(1(有),0(没有))\n");
    scanf("%d",&IncInfo);
    getchar();
    for(i=0; i<G.vexnum; ++i) //构造顶点向量
    {
        printf("请输入第%d个顶点:",i+1);
        scanf("%c",&G.vexs[i]);
        getchar();
    }
    for(i=0; i<G.vexnum; ++i) //初始化邻接矩阵
    {
        for(j=0; j<G.vexnum; ++j)
        {
            G.arcs[i][j].adj=INFINITY;
            G.arcs[i][j].info=NULL;
        }
    }
    for(k=0; k<G.arcnum; ++k) //构造邻接矩阵
    {
        printf("请输入一条弧连接的顶点及权值\n");
        printf("弧尾顶点:\n");//输入一条弧连接的顶点及权值
        scanf("%c",&v1);
        getchar();
        printf("弧头顶点:\n");
        scanf("%c",&v2);
        getchar();
        printf("权值:\n");
        scanf("%d",&w);
        getchar();
        i=LocateVex(G,v1);
        j=LocateVex(G,v2);//确定v1和v2在G中的位置
        G.arcs[i][j].adj=w;//弧<v1,v2>的权值
        if(IncInfo)
        {
            Input(G.arcs[i][j].info);//若弧含有相关信息,则输入
        }
    }
    return OK;
}//CreateDN

Status CreateUDG(Mgraph &G)//采用邻接矩阵表示法,构造无向图G
{
    int IncInfo,i,j,k;
    char v1,v2;
    printf("请输入图的顶点数(1~20):\n");
    scanf("%d",&G.vexnum);
    getchar();
    printf("请输入图的弧数:\n");
    scanf("%d",&G.arcnum);
    getchar();
    printf("各弧是否含有其他信息(1(有),0(没有))\n");
    scanf("%d",&IncInfo);
    getchar();
    for(i=0; i<G.vexnum; ++i) //构造顶点向量
    {
        printf("请输入第%d个顶点:",i+1);
        scanf("%c",&G.vexs[i]);
        getchar();
    }
    for(i=0; i<G.vexnum; ++i) //初始化邻接矩阵
    {
        for(j=0; j<G.vexnum; ++j)
        {
            G.arcs[i][j].adj=INFINITY;
            G.arcs[i][j].info=NULL;
        }
    }
    for(k=0; k<G.arcnum; ++k) //构造邻接矩阵
    {
        printf("请输入一条弧连接的顶点\n");
        printf("弧尾顶点:\n");//输入一条弧依附的顶点
        scanf("%c",&v1);
        getchar();
        printf("弧头顶点:\n");
        scanf("%c",&v2);
        getchar();
        i=LocateVex(G,v1);
        j=LocateVex(G,v2);//确定v1和v2在G中的位置
        G.arcs[i][j].adj=1;//v1和v2的连接关系
        if(IncInfo)
        {
            Input(G.arcs[i][j].info);//若弧含有相关信息,则输入
        }
        G.arcs[j][i]=G.arcs[i][j];//置<v1,v2>的对称弧<v2,v1>
    }
    return OK;
}//CreateUDG

Status CreateUDN(Mgraph &G)//采用邻接矩阵表示法,构造无向网G
{
    int IncInfo,i,j,k,w;
    char v1,v2;
    printf("请输入图的顶点数(1~20):\n");
    scanf("%d",&G.vexnum);
    getchar();
    printf("请输入图的弧数:\n");
    scanf("%d",&G.arcnum);
    getchar();
    printf("各弧是否含有其他信息(1(有),0(没有)):\n");
    scanf("%d",&IncInfo);
    getchar();
    for(i=0; i<G.vexnum; ++i)
    {
        printf("请输入第%d个顶点:",i+1);
        scanf("%c",&G.vexs[i]);
        getchar();
    }//构造顶点向量
    for(i=0; i<G.vexnum; ++i)
    {
        for(j=0; j<G.vexnum; ++j)
        {
            G.arcs[i][j].adj=INFINITY;
            G.arcs[i][j].info=NULL;
        }
    }//初始化邻接矩阵
    for(k=0; k<G.arcnum; ++k) //构造邻接矩阵
    {
        printf("请输入一条弧连接的顶点及权值\n");
        printf("弧尾顶点:\n");//输入一条弧连接的顶点及权值
        scanf("%c",&v1);
        getchar();
        printf("弧头顶点:\n");
        scanf("%c",&v2);
        getchar();
        printf("权值:\n");
        scanf("%d",&w);
        getchar();
        i=LocateVex(G,v1);
        j=LocateVex(G,v2);//确定v1和v2在G中的位置
        G.arcs[i][j].adj=w;//弧<v1,v2>的权值
        if(IncInfo)
        {
            Input(G.arcs[i][j].info);//若弧含有相关信息,则输入
        }
        G.arcs[j][i]=G.arcs[i][j];//置<v1,v2>的对称弧<v2,v1>
    }
    return OK;
}//CreateUDN


Status FirstAdjVex(Mgraph G,int v)//返回v的第一个邻接顶点
{
    int i;
    if(v>=0&&v<G.vexnum)
    {
        for(i=0; i<G.vexnum; i++)
        {
            if(G.arcs[v][i].adj)
            {
                return i;
            }
        }
    }
    return -1;
}//FirstAdjVex

Status NextAdjVex(Mgraph G,int v,int w)//返回v的(相对于w的)下一个邻接顶点
{
    int i;
    if(v>=0 && v<G.vexnum)
    {
        if(w>=0 && w<G.vexnum)
        {
            for(i=w+1; i<G.vexnum; i++)
            {
                if(G.arcs[v][i].adj)
                {
                    return i;
                }
            }
        }
    }
    return -1;
}//NextAdjVex

void Print_JZ(Mgraph G)//打印矩阵
{
    int i,j;
    for(i=0; i<G.vexnum; i++)
    {
        for(j=0; j<G.vexnum; j++)
        {
            printf("%d ",G.arcs[i][j].adj);
        }
        printf("\n");
    }
}

void Print(Mgraph G,int v)
{
    printf("%c",G.vexs[v]);
}

void DFS(Mgraph G,int v)
{
    //从第v个顶点出发递归地深度优先遍历图G
    int w;
    visited[v]=TRUE;
    VisitFunc(G,v);//访问第v个顶点
    for(w=FirstAdjVex(G,v); w>0; w=NextAdjVex(G,v,w))
    {
        if(!visited[w])
        {
            DFS(G,w);//对v的尚未访问的邻接顶点w递归调用DFS
        }
    }
}//DFS

void DFSTraverse(Mgraph G,void (*Print)(Mgraph G,int v))
{
    //对图G做深度优先遍历
    int v;
    VisitFunc=Print;//使用全局变量VisitFunc,使DFS不必设函数指针参数
    for(v=0; v<G.vexnum; ++v)
    {
        visited[v]=FALSE;//访问标志数组初始化
    }
    for(v=0; v<G.vexnum; ++v)
    {
        if(!visited[v])
        {
            DFS(G,v);//对尚未访问的顶点调用DFS
        }
    }
}//DFSTraverse

int main()
{
    char Ch;
    Mgraph G;
    while(1)
    {
        system("cls");
        printf("请选择操作:\n");
        printf("1.构造有向图\n2.构造有向网\n3.构造无向图\n4.构造无向网\n5.退出\n");
        scanf("%c",&Ch);
        getchar();
        switch(Ch)
        {
        case '1':
            CreateDG(G);//构造有向图G
            printf("有向图G的邻接矩阵为:\n");
            Print_JZ(G);
            printf("有向图G的深度优先遍历:\n");
            DFSTraverse(G,Print);
            getchar();
            system("pause");
            break;
        case '2':
            CreateDN(G);//构造有向网G
            printf("有向网G的邻接矩阵为:\n");
            Print_JZ(G);
            printf("有向网G的深度优先遍历:\n");
            DFSTraverse(G,Print);
            getchar();
            system("pause");
            break;
        case '3':
            CreateUDG(G);//构造无向图G
            printf("无向图G的邻接矩阵为:\n");
            Print_JZ(G);
            printf("无向图G的深度优先遍历:\n");
            DFSTraverse(G,Print);
            getchar();
            system("pause");
            break;
        case '4':
            CreateUDN(G);//构造无向网G
            printf("无向网G的邻接矩阵为:\n");
            Print_JZ(G);
            printf("无向网G的深度优先遍历:\n");
            DFSTraverse(G,Print);
            getchar();
            system("pause");
            break;
        case '5':
            exit(0);
            break;
        default:
            printf("选择错误!\n");
            system("pause");
        }
        return 0;
    }
}


运行效果如图:

使用了邻接矩阵和深度优先算法

posted @ 2019-06-09 10:42  xiuzhublog  阅读(3097)  评论(0编辑  收藏  举报