第十二周 项目二【操作用邻接表存储的图】

来源:互联网 发布:英才网络文化传媒 编辑:程序博客网 时间:2024/05/18 02:53
/*问题及代码  *Copyright(c)2016,烟台大学计算机学院  *All right reserved.  *文件名称:操作用邻接表存储的图.cpp  *作者:李潇  *完成日期;2016年11月17日  *版本号;v1.0  *问题描述:           假设图G采用邻接表存储,分别设计实现以下要求的算法:  (1)输出出图G中每个顶点的出度;  (2)求出图G中出度最大的一个顶点,输出该顶点编号;  (3)计算图G中出度为0的顶点数;  (4)判断图G中是否存在边<i,j>。  利用下图作为测试用图,输出结果。  这里写图片描述   *输入描述:图的邻接矩阵  *程序输出:图中各顶点出度,最大出度顶点信息,出度为0的顶点,某边是否存在。 */  //功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图  //参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)  //      n - 矩阵的阶数  //      g - 要构造出来的邻接矩阵数据结构 

//graph.h#ifndef GRAPH_H_INCLUDED  #define GRAPH_H_INCLUDED    #define MAXV 100                //最大顶点个数  #define INF 99999       //INF表示∞  typedef int InfoType;    //以下定义邻接矩阵类型  typedef struct  {      int no;                     //顶点编号      InfoType info;              //顶点其他信息,在此存放带权图权值  } VertexType;                   //顶点类型    typedef struct                  //图的定义  {      int edges[MAXV][MAXV];      //邻接矩阵      int n,e;                    //顶点数,弧数      VertexType vexs[MAXV];      //存放顶点信息  } MGraph;                       //图的邻接矩阵类型    //以下定义邻接表类型  typedef struct ANode            //弧的结点结构类型  {      int adjvex;                 //该弧的终点位置      struct ANode *nextarc;      //指向下一条弧的指针      InfoType info;              //该弧的相关信息,这里用于存放权值  } ArcNode;    typedef int Vertex;    typedef struct Vnode            //邻接表头结点的类型  {      Vertex data;                //顶点信息      int count;                  //存放顶点入度,只在拓扑排序中用      ArcNode *firstarc;          //指向第一条弧  } VNode;    typedef VNode AdjList[MAXV];    //AdjList是邻接表类型    typedef struct  {      AdjList adjlist;            //邻接表      int n,e;                    //图中顶点数n和边数e  } ALGraph;                      //图的邻接表类型    void ArrayToMat(int *Arr, int n, MGraph &g); //用普通数组构造图的邻接矩阵  void ArrayToList(int *Arr, int n, ALGraph *&); //用普通数组构造图的邻接表  void MatToList(MGraph g,ALGraph *&G);//将邻接矩阵g转换成邻接表G  void ListToMat(ALGraph *G,MGraph &g);//将邻接表G转换成邻接矩阵g  void DispMat(MGraph g);//输出邻接矩阵g  void DispAdj(ALGraph *G);//输出邻接表G  int OutDegree(ALGraph *G,int v);  void OutDs(ALGraph *G);  void OutMaxDs(ALGraph *G);  void ZeroDs(ALGraph *G);  bool Arc(ALGraph *G, int i,int j);  #endif // GRAPH_H_INCLUDED 

//graph.cpp#include <stdio.h>  #include <malloc.h>  #include "graph.h"  void ArrayToMat(int *Arr, int n, MGraph &g)  {      int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数      g.n=n;      for (i=0; i<g.n; i++)          for (j=0; j<g.n; j++)          {              g.edges[i][j]=Arr[i*n+j]; //将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j],计算存储位置的功夫在此应用              if(g.edges[i][j]!=0)                  count++;          }      g.e=count;  }    void ArrayToList(int *Arr, int n, ALGraph *&G)  {      int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数      ArcNode *p;      G=(ALGraph *)malloc(sizeof(ALGraph));      G->n=n;      for (i=0; i<n; i++)                 //给邻接表中所有头节点的指针域置初值          G->adjlist[i].firstarc=NULL;      for (i=0; i<n; i++)                 //检查邻接矩阵中每个元素          for (j=n-1; j>=0; j--)              if (Arr[i*n+j]!=0)      //存在一条边,将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j]              {                  p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p                  p->adjvex=j;                  p->info=Arr[i*n+j];                  p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p                  G->adjlist[i].firstarc=p;              }        G->e=count;  }    void MatToList(MGraph g, ALGraph *&G)  //将邻接矩阵g转换成邻接表G  {      int i,j;      ArcNode *p;      G=(ALGraph *)malloc(sizeof(ALGraph));      for (i=0; i<g.n; i++)                   //给邻接表中所有头节点的指针域置初值          G->adjlist[i].firstarc=NULL;      for (i=0; i<g.n; i++)                   //检查邻接矩阵中每个元素          for (j=g.n-1; j>=0; j--)              if (g.edges[i][j]!=0)       //存在一条边              {                  p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p                  p->adjvex=j;                  p->info=g.edges[i][j];                  p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p                  G->adjlist[i].firstarc=p;              }      G->n=g.n;      G->e=g.e;  }    void ListToMat(ALGraph *G,MGraph &g)  //将邻接表G转换成邻接矩阵g  {      int i,j;      ArcNode *p;      for (i=0; i<g.n; i++)   //先初始化邻接矩阵          for (j=0; j<g.n; j++)              g.edges[i][j]=0;      for (i=0; i<G->n; i++)  //根据邻接表,为邻接矩阵赋值      {          p=G->adjlist[i].firstarc;          while (p!=NULL)          {              g.edges[i][p->adjvex]=p->info;              p=p->nextarc;          }      }      g.n=G->n;      g.e=G->e;  }    void DispMat(MGraph g)  //输出邻接矩阵g  {      int i,j;      for (i=0; i<g.n; i++)      {          for (j=0; j<g.n; j++)              if (g.edges[i][j]==INF)                  printf("%3s","∞");              else                  printf("%3d",g.edges[i][j]);          printf("\n");      }  }    void DispAdj(ALGraph *G)  //输出邻接表G  {      int i;      ArcNode *p;      for (i=0; i<G->n; i++)      {          p=G->adjlist[i].firstarc;          printf("%3d: ",i);          while (p!=NULL)          {              printf("-->%d/%d ",p->adjvex,p->info);              p=p->nextarc;          }          printf("\n");      }  }  //返回图G中编号为v的顶点的出度  int OutDegree(ALGraph *G,int v)  {      ArcNode *p;      int n=0;      p=G->adjlist[v].firstarc;      while (p!=NULL)      {          n++;          p=p->nextarc;      }      return n;  }    //输出图G中每个顶点的出度  void OutDs(ALGraph *G)  {      int i;      for (i=0; i<G->n; i++)          printf("  顶点%d:%d\n",i,OutDegree(G,i));  }    //输出图G中出度最大的一个顶点  void OutMaxDs(ALGraph *G)  {      int maxv=0,maxds=0,i,x;      for (i=0; i<G->n; i++)      {          x=OutDegree(G,i);          if (x>maxds)          {              maxds=x;              maxv=i;          }      }      printf("顶点%d,出度=%d\n",maxv,maxds);  }  //输出图G中出度为0的顶点数  void ZeroDs(ALGraph *G)  {      int i,x;      for (i=0; i<G->n; i++)      {          x=OutDegree(G,i);          if (x==0)              printf("%2d",i);      }      printf("\n");  }    //返回图G中是否存在边<i,j>  bool Arc(ALGraph *G, int i,int j)  {      ArcNode *p;      bool found = false;      p=G->adjlist[i].firstarc;      while (p!=NULL)      {          if(p->adjvex==j)          {              found = true;              break;          }          p=p->nextarc;      }      return found;  }  

//main.cpp#include <stdio.h>  #include <malloc.h>  #include "graph.h"    int main()  {      ALGraph *G;      int A[7][7]=      {          {0,1,1,1,0,0,0},          {0,0,0,0,1,0,0},          {0,1,0,0,1,1,0},          {1,0,0,0,0,0,1},          {0,0,1,0,0,0,0},          {0,0,0,1,1,0,1},          {0,1,0,0,0,0,0}      };      ArrayToList(A[0], 7, G);      printf("(1)各顶点出度:\n");      OutDs(G);      printf("(2)最大出度的顶点信息:");      OutMaxDs(G);      printf("(3)出度为0的顶点:");      ZeroDs(G);      printf("(4)边<1,6>存在吗?");      if(Arc(G,1,6))          printf("是\n");      else          printf("否\n");      printf("\n");      printf("(4)边<5,6>存在吗?");      if(Arc(G,5,6))          printf("是\n");      else          printf("否\n");      printf("\n");      return 0;  }  


运行结果:

知识点总结:

求出度即是求从该点出发到其他点的边的总数,出度为0的就不言而喻了。

求最大出度就是在求出每点的出度之后作比较求出最大值(和求一个数组的最大值/或最小值的原理是一样的)。

判断<i,j>边是否存在,采用bool型函数,先判断行(i),再判断其是否是指向j的点

心得体会:

邻接表是链表形式的,操作起来比较方便

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机百度云网络出错怎么办 百度账号提示异常风险怎么办 刷xp框架卡米怎么办 全民k歌歌曲下架怎么办 全民k歌伴奏下架怎么办 苹果手机图片的图标打不开怎么办 电脑页面加载不出来怎么办 电脑主页面加载不出来怎么办 桌面图标不见了怎么办右键无反应 手机一直闪退该怎么办 点击华为设置闪退怎么办 小白摄像头获取视频文件失败怎么办 为什么解压文件老提示失败怎么办 b站sd卡写入失败怎么办 手机检测不到sd卡怎么办 华为sd卡不可用怎么办 u盘延缓写入失败怎么办 手机提示sd卡不可用怎么办 显示sd卡不可用怎么办 小米手机检测不到sd卡怎么办 小米手机sd卡写入失败怎么办 没有检测到sd卡怎么办 e站图片配额用尽怎么办 内存卡密码忘了怎么办 电脑上酷狗音乐播放失败怎么办 播放失败不支持该文件怎么办 手机山寨云资源失效怎么办 支付密码输错了怎么办 微信密码锁定了怎么办 电脑网易云音乐闪退怎么办 逆战耳机电流声怎么办 肠道感染一直吃药治不好怎么办 如果24小时以后还没到账该怎么办 在游戏平台充值没到账该怎么办 充值豪华黄钻没到账该怎么办 起点签到签满了怎么办 ipad锁屏声音小怎么办 扣扣邮箱文件超大了怎么办 网易邮箱图片已过期怎么办 邮箱里面的文件过期了怎么办 邮箱发的文件过期了怎么办