一、使用邻接矩阵
#include <>
#include <>
#define INFINITY 65535 //∞设为65535
#define MAXVERTEXNUM 100 //最大顶点数设为100
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; //顶点数
int Ne; //边数
int G[MAXVERTEXNUM][MAXVERTEXNUM]; //邻接矩阵
char Data[MAXVERTEXNUM];
};
typedef PtrToGNode MGraph; //以邻接矩阵存储的图类型
MGraph BuildGraph()
{
MGraph Graph;
int i,j,k,weight;
char a,b;
Graph = (PtrToGNode)malloc(sizeof(struct GNode));
printf("请输入顶点数和边数:");
scanf("%d %d",&Graph->Nv,&Graph->Ne);
for(i = 0;i < Graph->Nv; i++)
{
getchar(); //getchar()函数是输入一个字符,用此函数将scanf()未处理的量进行释放;
printf("请输入第%d个顶点,数组位置为%d:",i+1,i);
scanf("%c",&Graph->Data[i]); //输入顶点数据
}
for(i = 0;i < Graph->Nv; i++)
for(j = 0;j < Graph->Nv; j++)
Graph->G[i][j] = INFINITY; //初始化邻接矩阵
for(k = 0;k < Graph->Ne ; k++)
{
printf("请输入第%d条边的顶点信息与边的权值(格式为:起点数据 终点数据 权重):",k+1);
getchar();
scanf("%c %c %d",&a,&b,&weight);
for( i = 0; Graph->Data[i] != a;i++)
; //找到顶点a在邻接矩阵中的下标
for( j = 0; Graph->Data[j] != b;j++)
; //找到顶点b在邻接矩阵中的下标
Graph->G[i][j] = weight;
Graph->G[j][i] = weight;
}
return Graph;
}
//统计边的个数
int NeNum(MGraph Gr){
int number=0;
for(int i=0;i<Gr->Nv;i++){
for(int j=0;j<Gr->Nv;j++){
if(Gr->G[i][j]!=INFINITY){
number++;
}
}
}
return number/2;
}
//统计图中各顶点的度并输出
void PrintDeg(MGraph Gr){
for(int i=0;i<Gr->Nv;i++){
int number=0;
for(int j=0;j<Gr->Nv;j++){
if(Gr->G[i][j]!=INFINITY){
number++;
}
}
printf("顶点%c的度为%d\n",Gr->Data[i],number);
}
}
//统计网图的总权重
int MTWeight(MGraph Gr){
int number=0;
for(int i=0;i<Gr->Nv;i++){
for(int j=0;j<Gr->Nv;j++){
if(Gr->G[i][j]!=INFINITY){
number+=Gr->G[i][j];
}
}
}
return number/2;
}
//统计度为n的顶点个数
int WeightN(MGraph Gr,int N){
int number=0;
for(int i=0;i<Gr->Nv;i++){
for(int j=0;j<Gr->Nv;j++){
if(Gr->G[i][j]==N){
number++;
}
}
}
return number;
}
int main(){
MGraph Gr=BuildGraph();
int n;
n=NeNum(Gr);
printf("该图的边数为:%d\n",n);
PrintDeg(Gr);
n= MTWeight(Gr);
printf("该图的总权重为:%d\n",n);
int m;
printf("输入度:");
scanf("%d",&m);
n=WeightN(Gr,m);
printf("度为%d的顶点为:%d\n",m,n);
}
二、使用邻接表
#include <>
#include <>
#define MAXVERTEXNUM 100
//枚举图的种类 DG表示有向图, AG为无向图
typedef enum { DG=1,AG} GraphKind ;
//邻接点的定义
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
int AdjV; //邻接点的下标
PtrToAdjVNode Next; //指向下一个邻接点的指针
};
//顶点表头结点的定义
typedef struct VNode{
char Data; //顶点数据
PtrToAdjVNode FisrtEdge; //边表头指针
}AdjList[MAXVERTEXNUM]; //AdjList是邻接表类型
typedef struct GNode *PtrToGNode;
struct GNode{
GraphKind kind;
int Nv; //顶点数
int Ne; //边数
AdjList G; //邻接表
};
typedef PtrToGNode LGraph; //以邻接表方式存储的图类型
LGraph BuildGraph()
{
int v,i,k,j;
LGraph Graph;
PtrToAdjVNode NewNode;
Graph = (LGraph)malloc(sizeof(struct GNode));
printf("输入图的类型,1表示有向图(DG),2表示无向图(AG) :\n");
scanf("%d",&Graph->kind);
printf("输入顶点数和边数:\n");
scanf("%d %d",&Graph->Nv,&Graph->Ne);
//输入顶点信息
printf("输入顶点信息:\n");
for(v = 0;v < Graph->Nv; v++){
getchar();
scanf("%c",&Graph->G[v].Data);
Graph->G[v].FisrtEdge = NULL; //将指向边表的指针初始化
}
//建立边表
char vi,vj;
printf("输入边<vi,vj>中的顶点vi,vj:\n");
for(k = 0;k < Graph->Ne; k++){ //k记录插入边的个数
getchar();
scanf("%c %c",&vi,&vj);
for(i = 0; Graph->G[i].Data != vi; i++) ;//找vi在顶点数组中的下标
for(j = 0; Graph->G[j].Data != vj; j++) ;//找vj在顶点数组中的下标
//为vj建立新的邻接点
NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->AdjV = j;
NewNode->Next = Graph->G[i].FisrtEdge; //头插法插入边结点
Graph->G[i].FisrtEdge = NewNode;
//下面代码有向图无,无向图有
if(Graph->kind == AG){
NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->AdjV = i;
NewNode->Next = Graph->G[j].FisrtEdge; //头插法插入边结点
Graph->G[j].FisrtEdge = NewNode;
}
}
return Graph;
}
//打印邻接表
void outputG(LGraph Graph)
{
PtrToAdjVNode p;
printf("邻接表为:\n");
int i;
for(i = 0;i < Graph->Nv; i++){
p = Graph->G[i].FisrtEdge;
printf("%c ",Graph->G[i].Data);
while(p){
printf("->");
printf(" <%c,%c> ",Graph->G[i].Data,Graph->G[p->AdjV].Data);
p = p->Next;
}
printf("\n");
}
}
//统计边的个数
int NeNum(LGraph Gr){
int number=0;
for(int i=0;i<Gr->Nv;i++){
PtrToAdjVNode ptr=Gr->G[i].FisrtEdge;
while(ptr!=NULL){
number++;
ptr=ptr->Next;
}
}
if(Gr->kind==DG) return number;
else return number/2;
}
//统计各顶点的出度
int *outdeg(LGraph Gr){
int t[MAXVERTEXNUM];
for(int i=0;i<Gr->Nv;i++){
t[i]=0;
}
for(int i=0;i<Gr->Nv;i++){
int number=0;
PtrToAdjVNode ptr=Gr->G[i].FisrtEdge;
while(ptr!=NULL){
number++;
ptr=ptr->Next;
}
t[i]=number;
}
return t;
}
//统计个顶点的入度
int *indeg(LGraph Gr){
int t5[MAXVERTEXNUM];
for(int i=0;i<Gr->Nv;i++){
t5[i]=0;
}
for(int i=0;i<Gr->Nv;i++){
// int number=0;
PtrToAdjVNode ptr=Gr->G[i].FisrtEdge;
while(ptr!=NULL){
t5[ptr->AdjV]++;
ptr=ptr->Next;
}
// t[i]=number;
}
return t5;
}
//统计出度为n的顶点个数
int outdegN(LGraph Gr,int N){
int *t2;
t2=outdeg(Gr);
int number=0;
for(int i=0;i<Gr->Nv;i++){
if(t2[i]==N){
number++;
}
}
return number;
}
//统计入度为n的顶点个数
int indegN(LGraph Gr,int N){
int *t3;
t3=indeg(Gr);
int number=0;
for(int i=0;i<Gr->Nv;i++){
if(t3[i]==N){
number++;
}
}
return number;
}
int main(){
LGraph Gr=BuildGraph();
printf("统计图中边的个数并输出:");
int N=NeNum(Gr);
printf("%d\n",N);
//各顶点的出度
int *t2;
t2=outdeg(Gr);
for(int i=0;i<Gr->Nv;i++){
printf("顶点%c的出度为:%d\n",Gr->G[i].Data,t2[i]);
}
int *t3;
t3=indeg(Gr);
for(int i=0;i<Gr->Nv;i++){
printf("顶点%c的入度为:%d\n",Gr->G[i].Data,t3[i]);
}
//统计出度为n的顶点数
int n;
printf("请输入要统计的出度:");
scanf("%d",&n);
printf("出度为%d的节点数为:%d\n",n,outdegN(Gr,n));
//统计入度为n的定点数
printf("请输入要统计的入度:");
scanf("%d",&n);
printf("入度为%d的节点数为:%d\n",n,indegN(Gr,n));
}