zoukankan      html  css  js  c++  java
  • 数据结构 实验五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表示是否相邻,网为权值
        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): ");
        scanf("%d",&G.vexnum);
        getchar();
        printf("请输入图的弧数: ");
        scanf("%d",&G.arcnum);
        getchar();
        printf("各弧是否含有其他信息(1(有),0(没有)): ");
        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("请输入一条弧连接的顶点: ");
            printf("弧尾顶点: ");//输入一条弧依附的顶点
            scanf("%c",&v1);
            getchar();
            printf("弧头顶点: ");
            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): ");
        scanf("%d",&G.vexnum);
        getchar();
        printf("请输入图的弧数: ");
        scanf("%d",&G.arcnum);
        getchar();
        printf("各弧是否含有其他信息(1(有),0(没有)) ");
        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("请输入一条弧连接的顶点及权值 ");
            printf("弧尾顶点: ");//输入一条弧连接的顶点及权值
            scanf("%c",&v1);
            getchar();
            printf("弧头顶点: ");
            scanf("%c",&v2);
            getchar();
            printf("权值: ");
            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): ");
        scanf("%d",&G.vexnum);
        getchar();
        printf("请输入图的弧数: ");
        scanf("%d",&G.arcnum);
        getchar();
        printf("各弧是否含有其他信息(1(有),0(没有)) ");
        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("请输入一条弧连接的顶点 ");
            printf("弧尾顶点: ");//输入一条弧依附的顶点
            scanf("%c",&v1);
            getchar();
            printf("弧头顶点: ");
            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): ");
        scanf("%d",&G.vexnum);
        getchar();
        printf("请输入图的弧数: ");
        scanf("%d",&G.arcnum);
        getchar();
        printf("各弧是否含有其他信息(1(有),0(没有)): ");
        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("请输入一条弧连接的顶点及权值 ");
            printf("弧尾顶点: ");//输入一条弧连接的顶点及权值
            scanf("%c",&v1);
            getchar();
            printf("弧头顶点: ");
            scanf("%c",&v2);
            getchar();
            printf("权值: ");
            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(" ");
        }
    }

    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("请选择操作: ");
            printf("1.构造有向图 2.构造有向网 3.构造无向图 4.构造无向网 5.退出 ");
            scanf("%c",&Ch);
            getchar();
            switch(Ch)
            {
            case '1':
                CreateDG(G);//构造有向图G
                printf("有向图G的邻接矩阵为: ");
                Print_JZ(G);
                printf("有向图G的深度优先遍历: ");
                DFSTraverse(G,Print);
                getchar();
                system("pause");
                break;
            case '2':
                CreateDN(G);//构造有向网G
                printf("有向网G的邻接矩阵为: ");
                Print_JZ(G);
                printf("有向网G的深度优先遍历: ");
                DFSTraverse(G,Print);
                getchar();
                system("pause");
                break;
            case '3':
                CreateUDG(G);//构造无向图G
                printf("无向图G的邻接矩阵为: ");
                Print_JZ(G);
                printf("无向图G的深度优先遍历: ");
                DFSTraverse(G,Print);
                getchar();
                system("pause");
                break;
            case '4':
                CreateUDN(G);//构造无向网G
                printf("无向网G的邻接矩阵为: ");
                Print_JZ(G);
                printf("无向网G的深度优先遍历: ");
                DFSTraverse(G,Print);
                getchar();
                system("pause");
                break;
            case '5':
                exit(0);
                break;
            default:
                printf("选择错误! ");
                system("pause");
            }
            return 0;
        }
    }


    运行效果如图:

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

  • 相关阅读:
    假期阅读笔记三
    软件需求最佳实践阅读笔记03
    学习进度条第八周
    软件需求最佳实践阅读笔记02
    学习进度条第七周
    软件需求与分析课堂讨论一
    学习进度第五周
    软件需求最佳实践阅读笔记01
    学习进度第四周
    学习进度条第三周
  • 原文地址:https://www.cnblogs.com/xiuzhublog/p/12608581.html
Copyright © 2011-2022 走看看