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

算法逻辑:
①首先,定义一个头节点数组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;
}

浙公网安备 33010602011771号