zoukankan      html  css  js  c++  java
  • 数据结构实验报告-实验四 图的构造与遍历

    实验四   图的构造与遍历

     

    实验目的

    1、图的的定义和遍历

    (1)掌握图的邻接矩阵、邻接表的表示方法。

    (2)掌握建立图的邻接矩阵的算法。

    (3)掌握建立图的邻接表的算法。

    (4)加深对图的理解,逐步培养解决实际问题的能力。

    实验内容

    1、图的定义和遍历

    (一)基础题

    1、编写图基本操作函数:

    (1)CreateALGraph(ALGraph &G) 建立无向图的邻接表表示;

    (2)LocateVex(ALGraph &G,char v)图查找信息;

    (3)DFSTraverse(ALGraph &G)图的深度遍历操作

    (4)BFSTraverse(ALGraph &G)图的广度优先遍历

    (5)Create(MGraph &G)邻接矩阵的创建

    2、调用上述函数实现下列操作:

    (1)建立一个图的邻接矩阵和图的邻接表;

    (2)采用递归深度优先遍历输出图的邻接矩阵;

    (3)采用递归深度优先输出图的邻接表;

    (4)采用图的广度优先遍历输出图的邻接表;

    (5)采用图的广度优先遍历输出图的邻接表。

    (二)提高题-

    【问题描述】设某城市有n个车站,并有m条公交线路连接这些车站。假设这些公交车站都是单向的,这n个车站被顺序编号为0~n-1。在本程序中输入该城市的公交线路数,车站个数以及各公交线路上各站的编号。

    【实现要求】求得从站0出发乘公交车至站n-1的最少换车次数。

    实验结果

    1、图的定义和遍历

    (一)基础题

    (1)画出数据结构基本运算的流程图

     
       

    (2)程序运行主要结果截图

    (3)程序源代码

    #include<stdio.h>
    
    #include<stdlib.h>
    
    typedef struct ArcNode
    
    {
    
        int adjvex;  //邻接点域
    
        struct ArcNode *nextarc; //指向下一个邻接点的指针域
    
        int weight;
    
    }ArcNode;//边结点
    
    typedef struct VNode
    
    {
    
        char vertex;   //顶点域
    
        ArcNode *firstarc;//第一条边的指针
    
    }VNode,AdjList[10];//顶点结点向量
    
    typedef struct
    
    {
    
        AdjList adjlist;
    
        int vexnum,arcnum;
    
    }ALGraph;
    
    //图的邻接矩阵
    
    typedef struct
    
    {
    
        int adj;
    
    }AdjMatrix[10][10];
    
    typedef struct
    
    {
    
        int vexs[10];
    
        AdjMatrix arcs;
    
        int vexnum,arcnum;
    
    }MGraph;
    
    int LocateVex(ALGraph &G,char v)//查找顶点信息
    
    {
    
        int k,j=0;
    
        for(k=0;k<G.vexnum;k++)
    
          if(G.adjlist[k].vertex==v)
    
          {
    
              j=k;
    
              break;
    
          }
    
          return j;
    
    }
    
    void CreateALGraph(ALGraph &G)
    
    {//建立无向图的邻接表表示
    
        int i,j,k,w;
    
        char v1,v2;
    
        ArcNode *s;
    
        printf("请输入顶点数和边数(vexnum,arcnum):");
    
        scanf("%d,%d",&G.vexnum,&G.arcnum);
    
        for(i=0;i<G.vexnum;i++)
    
        {//建立顶点表
    
            getchar();
    
            printf("请输入第%d顶点信息:",i+1);
    
            scanf("%c",&G.adjlist[i].vertex);//读入顶点信息
    
            G.adjlist[i].firstarc=NULL;//边表置为空表
    
        }
    
        for(k=0;k<G.arcnum;k++)
    
        {//建立边表
    
            getchar();
    
            printf("请输入第%d边的顶点对序号和边的权值(v1,v2,w):",k+1);
    
            scanf("%c,%c,%d",&v1,&v2,&w);
    
            j=LocateVex(G,v2);
    
            i=LocateVex(G,v1);
    
            s=(ArcNode*)malloc(sizeof(ArcNode)); //生成边表结点
    
            s->adjvex=j;//邻接点序号为j
    
            s->weight=w;//权值
    
            s->nextarc=G.adjlist[i].firstarc;
    
            G.adjlist[i].firstarc=s; //将新结点*s插入顶点vi的边表头部
    
            //若图为无向图则加上下面的四句代码,若图为有向图则注释下面的四句代码
    
            s=(ArcNode*)malloc(sizeof(ArcNode));
    
            s->adjvex=i;
    
            s->weight=w;
    
            s->nextarc=G.adjlist[j].firstarc;
    
            G.adjlist[j].firstarc=s;
    
        }
    
    }
    
    bool visited[20];
    
    int v;
    
    void DFS(ALGraph &G,int v)//深度遍历输出
    
    {
    
        visited[v]=true;
    
        printf("%c ",G.adjlist[v].vertex);
    
        ArcNode *w;
    
        for(w=G.adjlist[v].firstarc;w!=NULL;w=w->nextarc)
    
            if(!visited[w->adjvex])
    
            DFS(G,w->adjvex);
    
    }
    
    void DFSTraverse(ALGraph &G)//图的深度遍历操作
    
    {
    
        for(v=0;v<G.vexnum;v++)
    
            visited[v]=false;
    
        for(v=0;v<G.vexnum;v++)
    
            if(!visited[v])
    
            DFS(G,v);
    
    }
    
    //队列
    
    typedef struct QNode
    
    {
    
        int data;
    
        struct QNode *next;
    
    }QNode,*QueuePtr;
    
    typedef struct
    
    {
    
        QueuePtr front;
    
        QueuePtr rear;
    
    }LinkQueue;
    
    void InitQueue(LinkQueue &Q)//构造一个空队列 Q 
    
    {
    
        Q.rear=Q.front=(QueuePtr)malloc(sizeof(QNode));
    
        Q.front->next=NULL;
    
    }
    
    void EnQueue(LinkQueue &Q,int e)//入队
    
    {
    
        QNode *p;
    
        p=(QueuePtr)malloc(sizeof(QNode));
    
        p->data=e;
    
        p->next=NULL;
    
        Q.rear->next=p;
    
        Q.rear=p;
    
    }
    
    void DeQueue(LinkQueue &Q,int &e2)
    
    {//出队
    
        QNode *p;
    
        p=Q.front->next;
    
        e2=p->data;
    
        Q.front->next=p->next;
    
        if(Q.rear==p)
    
            Q.rear=Q.front;
    
        free(p);
    
    }
    
    bool visited1[20];
    
     
    
    void BFSTraverse(ALGraph &G)//图的广度优先遍历
    
    {
    
     
    
        for(v=0;v<G.vexnum;v++)
    
            visited1[v]=false;
    
        LinkQueue Q;
    
        InitQueue(Q);
    
        for(v=0;v<G.vexnum;v++)
    
            if(!visited1[v])
    
        {
    
            visited1[v]=true;
    
            printf("%c ",G.adjlist[v].vertex);
    
            EnQueue(Q,v);
    
            int u;
    
            ArcNode *w;
    
            while(Q.front!=Q.rear)
    
            {
    
                DeQueue(Q,u);
    
                for(w=G.adjlist[u].firstarc;w!=NULL;w=w->nextarc)
    
                    if(!visited1[w->adjvex])
    
                {
    
                    visited1[w->adjvex]=true;
    
                    printf("%c ",G.adjlist[w->adjvex].vertex);
    
                    EnQueue(Q,w->adjvex);
    
                }
    
            }
    
        }
    
    }
    
    void display(ALGraph &G)//输出图的顶点信息
    
    {
    
        printf("建立的邻接表位:
    ");
    
        int i;
    
        for(i=0;i<G.vexnum;i++)
    
        {
    
            if(G.adjlist[i].firstarc!=NULL)
    
            {
    
                printf("%c->",G.adjlist[i].vertex);
    
                ArcNode *p;
    
                p=G.adjlist[i].firstarc;
    
                while(p!=NULL)
    
                {
    
                    printf("%d->",p->adjvex);
    
                    p=p->nextarc;
    
                }
    
                printf("NULL
    ");
    
            }
    
            else
    
            {
    
                printf("%c->NULL
    ",G.adjlist[i].vertex);
    
            }
    
        }
    
    }
    
     
    
    int LocateVex(MGraph &G,int v)
    
    {
    
        int k,j=0;
    
        for(k=0;k<G.vexnum;k++)
    
            if(G.vexs[k]==v)
    
        {
    
            j=k;
    
            break;
    
        }
    
        return j;
    
    }
    
    void Create(MGraph &G)
    
    {
    
        int i,j,k;
    
        int v1=0,v2=0,w=0;
    
        printf("请输入图的顶点数:");
    
        scanf("%d",&G.vexnum);
    
        printf("请输入图的边数:");
    
        scanf("%d",&G.arcnum);
    
        for(i=0;i<G.vexnum;i++)
    
            G.vexs[i]=i+1;
    
        for(i=0;i<G.vexnum;i++)
    
            for(j=0;j<G.vexnum;j++)
    
            G.arcs[i][j].adj=0;
    
        for(k=0;k<G.arcnum;k++)
    
        {
    
            printf("请输入一条边依附的顶点v1,v2及权值(v1,v2,w):");
    
            scanf("%d,%d,%d",&v1,&v2,&w);
    
            i=LocateVex(G,v1);
    
            j=LocateVex(G,v2);
    
            G.arcs[i][j].adj=w;
    
        }
    
    }
    
    void display(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("
    ");
    
        }
    
    }
    
     
    
    int main()
    
    {
    
        int z;
    
        printf("请输入选择:
    -1-建立图的邻接矩阵
    -2-建立图的邻接表
    ");
    
        scanf("%d",&z);
    
        if(z==1)
    
        {
    
             MGraph G;
    
             Create(G);
    
             display(G);
    
             scanf("%d",&z);
    
        }
    
        if(z==2)
    
        {
    
        ALGraph G;
    
        CreateALGraph(G);//建立无向图邻接表
    
        display(G);//输出图的的顶点信息
    
        printf("
    
    ");
    
        printf("图的深度遍历为:
    ");
    
        DFSTraverse(G);
    
        printf("
    ");
    
        printf("
    
    ");
    
        printf("图的广度遍历为:");
    
        BFSTraverse(G);
    
        printf("
    ");
    
        }
    
    }

    (二)提高题

    (1)画出数据结构基本运算的流程图

     
       

    (2)程序运行主要结果截图

    (3)程序源代码

      1 #include<stdio.h>
      2 
      3 #define M 20
      4 
      5 #define N 50
      6 
      7 int a[N+1];
      8 
      9 int g[N][N];
     10 
     11 int dist[N];
     12 
     13 int m=0,n=0;
     14 
     15 void buildG()//建图
     16 
     17 {
     18 
     19     int i,j,k,sc,dd;
     20 
     21     while(1)
     22 
     23     {
     24 
     25         printf("输入公交线路数[1-%d],公交站数[1-%d]
    ",M,N);
     26 
     27         scanf("%d %d",&m,&n);
     28 
     29         if(m>=1&&m<=M&&n>=1&&n<=N)
     30 
     31             break;
     32 
     33     }
     34 
     35     for(i=0;i<n;i++)
     36 
     37         for(j=0;j<n;j++)
     38 
     39         g[i][j]=0;
     40 
     41     for(i=0;i<m;i++)
     42 
     43     {
     44 
     45         printf("沿第%d条公交车线路前进方向的各站编号(0<=编号<=%d,-1结束):
    ",i+1,n-1);
     46 
     47         sc=0;
     48 
     49         while(1)
     50 
     51         {
     52 
     53             scanf("%d",&dd);
     54 
     55             if(dd==-1)
     56 
     57                 break;
     58 
     59             if(dd>=0&&dd<n)
     60 
     61                 a[sc++]=dd;
     62 
     63         }
     64 
     65         a[sc]=-1;
     66 
     67         for(k=1;a[k]>=0;k++)
     68 
     69             for(j=0;j<k;j++)
     70 
     71             g[a[j]][a[k]]=1;
     72 
     73 }
     74 
     75 }
     76 
     77 int minLen()
     78 
     79 {
     80 
     81     int j,k;
     82 
     83     for(j=0;j<n;j++)
     84 
     85         dist[j]=g[0][j];
     86 
     87     dist[0]=1;
     88 
     89     while(1)
     90 
     91     {
     92 
     93         for(k=-1,j=0;j<n;j++)
     94 
     95             if(dist[j]>0&&(k==-1||dist[j]<dist[k]))
     96 
     97             k=j;
     98 
     99         if(k<0||k==n-1)
    100 
    101             break;
    102 
    103         dist[k]=-dist[k];
    104 
    105         for(j=1;j<n;j++)
    106 
    107             if(g[k][j]==1&&(dist[j]==0||-dist[k]+1<dist[j]))
    108 
    109             dist[j]=-dist[k]+1;
    110 
    111     }
    112 
    113     j=dist[n-1];
    114 
    115     return(k<0?-1:j-1);
    116 
    117 }
    118 
    119 int main()
    120 
    121 {
    122 
    123     int t;
    124 
    125     buildG();
    126 
    127     t=minLen();
    128 
    129     if(t<0)
    130 
    131         printf("无解!
    ");
    132 
    133     else
    134 
    135         printf("从0号站到%d站需换车%d次
    ",n-1,t);
    136 
    137 }
    View Code
  • 相关阅读:
    browser-sync events.js:85 throw er; // Unhandled 'error' event
    js判断页面放大缩小
    uniapp小实例-新闻列表及详情
    uniapp 分享接口
    uniapp--第三方登录 小程序登录
    vue h5转换uni-app指南(vue转uni、h5转uni)
    uniapp详解及配置
    uniapp快速上手
    Vuex 的项目实例11 列表数据的按需切换
    Vuex 的项目实例10 底部按钮高亮切换
  • 原文地址:https://www.cnblogs.com/hakim-laohu/p/6639095.html
Copyright © 2011-2022 走看看