数据结构:不带权有向图的邻接矩阵和邻接表储存及求出入度实现

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;
}





  • 15
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值