图——邻接表

题目:假设有向图采用邻接表存储,求图中顶点的入度和出度并输出。

算法逻辑:

①首先,定义一个头节点数组g,用于存储头节点信息;定义一个存储相邻节点的结构体指针类型变量p,用于输出头结点信息;

②定义一个createLinkGraph函数,用于创建邻接表;定义一个LocateVertex函数,用于返回顶点v在图g中的位置;调用这两个函数创建邻接表;

③定义一个GetVertex函数,用于返回图g中的第i个顶点的值;调用该函数在循环中输出邻接表;

④定义一个VertexData类型的变量c,用于存放要求的顶点的信息;定义一个count函数,用于算入度数和出度数,调用该函数输出要求顶点的入度数和出度数。

源代码:

#include<stdio.h>
#include<stdlib.h>
#define NULL 0
#define MAX_VERTEX_NUM 10

typedef char VertexData;
typedef struct ArcNode{ //相邻节点
  int adjvex; /*该弧指向顶点的位置*/
  struct ArcNode *nextarc; /*指向下一条弧的指针*/
  int weight; /*权重*/
} ArcNode;

typedef struct VertexNode{ //头节点
  VertexData data; /*顶点数据*/
  ArcNode *firstarc; /*指向该顶点第一条弧的指针*/
} VertexNode;

typedef struct{ //头节点数组
  VertexNode vexs[MAX_VERTEX_NUM]; /*顶点向量*/
  int vexnum, arcnum; /*图的顶点数和弧数*/
} AdjList; /*(Adjacency Matrix Graph)*/


//顶点v在图G中存在,则返回顶点v在图G中的位置。
int LocateVertex(AdjList *g,VertexData v)
{
  int i;
  for(i=0;i<g->vexnum;i++){
    if(g->vexs[i].data==v){
      return i;
    }
  }
  return -1;
}
//返回图G中的第i个顶点的值。若i大于图G中顶点数,则函数返回值为“空”
VertexData GetVertex(AdjList *g,int i)
{
  return g->vexs[i].data;
}
//创建邻接表
void createLinkGraph(AdjList *g)
{
  int n;
  int i,j,weight;
  char v,w;
  int vi,vw; //顶点v和w所对应的位置
  ArcNode *p;
  printf("请输入图的顶点个数: ");
  scanf("%d",&n);
  g->vexnum=n;
  for(i=1;i<=n;i++){
    printf("请输入第%d个顶点的信息: ",i);
    scanf(" %c",&v);
    g->vexs[i-1].data=v;
    g->vexs[i-1].firstarc=NULL;
  }
  printf("请输入图的边数: ");
  scanf("%d",&n);
  g->arcnum=n;
  for(i=1;i<=n;i++){
    printf("请输入第%d个边的信息: ",i);
    scanf(" %c,%c,%d",&v,&w,&weight);
    vi=LocateVertex(g,v);//找顶点v的下标
    vw=LocateVertex(g,w);//找顶点w的下标
    //更新邻接矩阵的值
    if(vi==-1 || vw==-1){
      continue;
    }
    p = (ArcNode*)malloc(sizeof(ArcNode));
    p->adjvex = vw;
    p->weight=weight;
    p->nextarc = g->vexs[vi].firstarc;
    g->vexs[vi].firstarc = p;
  }
}

int outcount=0,incount=0; //用来存储出度数和入度数
void count(AdjList *g,VertexData c){
  int l;
  l=LocateVertex(g,c); //l存储顶点c的在邻接表头节点数组中的位置
  ArcNode *p; //p指向头节点的指针域,即头节点第一个邻接点的地址
  p = g->vexs[l].firstarc;
  //求出度
  if (p!=NULL){ //只要p有出度,头节点的指针域就不为空
    outcount++; //出度数加一
    //p指向该节点的指针域,判断是否有下一个邻接点
    while (p->nextarc!=NULL){
      outcount++; //出度数加一
      p = p->nextarc; //指向下一个邻接点继续循环
    }
  }else {
    //若头节点指针域为空,无操作
  }
  //求入度
  int i,j;
  for (i=0;i<g->vexnum;i++){ //对每个顶点进行判断
    //p指向头节点的指针域,即头节点第一个邻接点的地址
    p = g->vexs[i].firstarc;
    while (p!=NULL){ //有出度就不为空
      if (p->adjvex==l){ //判断顶点i指向的的顶点位置是否为l
        incount++; //若是,即入度数加一
      }
      p = p->nextarc; //指向下一个邻接点继续循环
    }
  }
}

int main(){
  AdjList g; //定义一个头节点数组
  int i,j;
  ArcNode *p;
  createLinkGraph(&g); //创建邻接表
  printf("\n邻接表如下: \n");
  for(i=0;i<g.vexnum;i++) //输出邻接表
  {
    //输出头结点信息
    printf("%c",g.vexs[i].data);
    p = g.vexs[i].firstarc;
    while(p!=NULL){
      printf("->%c",GetVertex(&g,p->adjvex));
      p = p->nextarc;
    }
    printf("\n");
  }
  printf("\n请输入要求入度数和出度数的顶点: ");
  VertexData c;
  getchar();
  scanf("%c",&c);getchar(); //输入要求的顶点
  outcount=0;incount=0; //初始化度数和出度数为零
  count(&g,c); //计算入度数和出度数
  printf("\n%c顶点的出度是:%d\n",c,outcount);
  printf("%c顶点的入度是:%d\n",c,incount);

  return 0;
}

posted @ 2024-04-25 17:10  ulyee  阅读(150)  评论(0)    收藏  举报