14.假设不带权有向图采用邻接矩阵G存储,设计实现以下功能的算法。
(1) 求出图中每个顶点的入度。
(2)求出图中每个顶点的出度。
(3)求出图中出度为0的顶点数。
15. 假设不带权有向图采用邻接表G存储,设计实现以下功能的算法。
(1) 求出图中每个顶点的入度。
(2)求出图中每个顶点的出度。
(3)求出图中出度为0的顶点数。
#include <stdio.h>
#include <stdlib.h>
#define MAX_V 5
#define INF 2147483647
//图的邻接矩阵结构
typedef struct
{
int No; //顶点编号
char info; //顶点信息,这里用作顶点名
} Ver;
typedef struct //图的邻接矩阵结构
{
int adjMat[MAX_V][MAX_V]; //邻接矩阵
int v; //点的个数
int e; //边的个数
Ver ver[MAX_V]; //顶点数组用于盛放顶点信息
} MatGraph;
//图的邻接表结构
typedef struct edgeNode //邻接表边节点
{
int adjVNo; //邻接点编号∵题目规定为不带权图∴不设权值的空间
struct edgeNode *next; //下一条边的指针
} ENode;
typedef struct
{
char info; //顶点信息,这里用作顶点名
ENode * first; //邻接表中边节点链表的头指针,指向第一个边节点
} VNode; //邻接表头结点,也是顶点类型
typedef struct
{
VNode Ver[MAX_V]; //邻接表头结点数组,也是顶点数组
int v; //点的个数
int e; //边的个数
} AdjGraph;
void CreateMat(MatGraph *&G,int A[MAX_V][MAX_V],int v,int e) //创建图的邻接矩阵
{
int i,j;
G=(MatGraph*)malloc(sizeof(MatGraph));
for(i=0;i<v;i++)
{
G->ver[i].No=i; //给节点编号
G->ver[i].info='A'+i; //这里节点信息域作为节点名,赋上A,B,C...字母
}
for(i=0;i<v;i++)
for(j=v-1;j>=0;j--)
G->adjMat[i][j]=A[i][j];
G->e=e;
G->v=v;
}
void CreateAdj(AdjGraph *&G,int A[MAX_V][MAX_V],int v,int e) //创建图的邻接表
{
int i,j;
ENode* p=NULL;
G=(AdjGraph*)malloc(sizeof(AdjGraph));
for(i=0;i<v;i++)
{
G->Ver[i].first=NULL;
G->Ver[i].info='A'+i; //这里节点信息域作为节点名,赋上A,B,C...字母
}
for(i=0;i<v;i++)
for(j=v-1;j>=0;j--)
if(A[i][j]!=0 && A[i][j]!=INF)
{
p=(ENode*)malloc(sizeof(ENode));
p->adjVNo=j;
p->next=G->Ver[i].first; //头插法
G->Ver[i].first=p;
}
G->e=e;
G->v=v;
}
void DispAdj(AdjGraph *G) //图的邻接表存储方式输出
{
int i;
ENode *p;
printf("图的邻接表存储\n");
for(i=0;i < G->v;i++)
{
p=G->Ver[i].first;
printf("编号%d的顶点%c:",i,G->Ver[i].info);
while(p!=NULL)
{
printf("%d→",p->adjVNo); //没有权,这里的链表只输出邻接顶点编号
p=p->next;
}
printf("NULL\n");
}
}
void DispMat(MatGraph *G) //图的邻接矩阵存储方式输出
{
int i,j;
printf("\n图的邻接矩阵存储\n");
for(i=0;i < G->v;i++)
{
printf("编号%d的顶点%c:",G->ver[i].No,G->ver[i].info);
for(j=0;j < G->v;j++)
printf("%d ",G->adjMat[i][j]); //没有权,这里的链表只输出邻接顶点编号
printf("\n");
}
}
void MatInDegree(MatGraph *G) //图的邻接矩阵存储方式求各顶点入度
{
int i,j,count; //count为顶点的人度
for(i=0;i < G->v;i++)
{
count=0;
printf("编号%d的顶点%c的入度为:",G->ver[i].No,G->ver[i].info);
for(j=0;j < G->v;j++)
if(G->adjMat[j][i]==1)
count++;
printf("%d\n",count);
}
}
void MatOutDegree(MatGraph *G) //图的邻接矩阵存储方式求各顶点出度
{
int i,j,count; //count为顶点的出度
for(i=0;i < G->v;i++)
{
count=0;
printf("编号%d的顶点%c的出度为:",G->ver[i].No,G->ver[i].info);
for(j=0;j < G->v;j++)
if(G->adjMat[i][j]==1)
count++;
printf("%d\n",count);
}
}
void MatZeroOutDegree(MatGraph *G) //图的邻接矩阵存储方式求出度为0的顶点个数
{
int i,j,count=0; //count为出度顶点的个数
for(i=0;i < G->v;i++)
{
for(j=0;j < G->v;j++)
if(G->adjMat[i][j]==1)
break;
if(j==G->v) //j==G->v说明邻接矩阵该行没有为1的值,既出度为0
count++;
}
printf("出度为0的顶点个数为%d\n",count);
}
void AdjInDegree(AdjGraph *G) //图的邻接表存储方式求各顶点入度
{
int i,j,count; //count为顶点的人度
ENode *p;
for(i=0;i < G->v;i++) //共G->v个节点
{
count=0;
printf("编号%d的顶点%c入度为:",i,G->Ver[i].info);
for(j=0;j < G->v;j++) //对每个节点都要遍历图的所有边
{
p=G->Ver[j].first;
while(p!=NULL)
{
if(p->adjVNo==i) //如果边节点的邻接顶点为现在要找的顶点,既当前正在遍历的顶点为该边终点时
count++; //则入度+1
p=p->next;
}
}
printf("%d\n",count);
}
}
void AdjOutDegree(AdjGraph *G) //图的邻接表存储方式求各顶点出度
{
int i,count; //count为顶点的出度
ENode *p;
for(i=0;i < G->v;i++)
{
p=G->Ver[i].first;
count=0;
printf("编号%d的顶点%c出度为:",i,G->Ver[i].info);
while(p!=NULL)
{
count++;
p=p->next;
}
printf("%d\n",count);
}
}
void AdjZeroOutDegree(AdjGraph *G) //图的邻接表存储方式求出度为0的顶点个数
{
int i,count=0; //count为出度顶点的个数
ENode *p;
for(i=0;i < G->v;i++)
{
if(G->Ver[i].first==NULL)
count++;
}
printf("出度为0的顶点个数为%d\n",count);
}
int main()
{
int adj_mat[MAX_V][MAX_V]=
{ //图的形状:
{0,1,0,1,0}, // 1
{0,0,1,1,0}, // ↙↓↖
{0,0,0,1,1}, // 2→ 3←0
{0,0,0,0,0}, // ↘↑↗
{1,0,0,1,0} // 4
};
int v=5,e=8;
MatGraph* MG=NULL;
AdjGraph* AG=NULL;
CreateMat(MG,adj_mat,v,e);
CreateAdj(AG,adj_mat,v,e);
DispAdj(AG);
DispMat(MG);
printf("\n14.图的邻接矩阵存储方式");
printf(" (1)\n ");
MatInDegree(MG);
printf(" (2)\n ");
MatOutDegree(MG);
printf(" (3)\n ");
MatZeroOutDegree(MG);
printf("\n15.图的邻接表存储方式");
printf(" (1)\n ");
AdjInDegree(AG);
printf(" (2)\n ");
AdjOutDegree(AG);
printf(" (3)\n ");
AdjZeroOutDegree(AG);
return 0;
}