实现图的邻接矩阵和邻接表的存储

编写一个程序graph.cpp,设计带权图的邻接矩阵和邻接表的创建和输出运算(包括邻接矩阵和邻接表之间的转换)


//图的基本运算算法
#include <stdio.h>
#include <malloc.h>
//图的两种存储结构
#define INF 32767    //定义∞
#define MAXV 100    //最大顶点个数
typedef char InfoType;

//以下定义邻接矩阵类型
typedef struct
{ int no;      //顶点编号
 InfoType info;    //顶点其他信息
} VertexType;     //顶点类型
typedef struct
{ int edges[MAXV][MAXV];  //邻接矩阵数组
 int n,e;     //顶点数,边数
 VertexType vexs[MAXV];  //存放顶点信息
} MatGraph;      //完整的图邻接矩阵类型

//以下定义邻接表类型
typedef struct ANode
{ int adjvex;     //该边的邻接点编号
 struct ANode *nextarc;  //指向下一条边的指针
 int weight;     //该边的相关信息,如权值(用整型表示)
} ArcNode;      //边结点类型
typedef struct Vnode
{ InfoType info;    //顶点其他信息
 int count;     //存放顶点入度,仅仅用于拓扑排序
 ArcNode *firstarc;   //指向第一条边
} VNode;      //邻接表头结点类型
typedef struct
{ VNode adjlist[MAXV];  //邻接表头结点数组
 int n,e;     //图中顶点数n和边数e
} AdjGraph;      //完整的图邻接表类型

void CreateMat(MatGraph &g,int A[MAXV][MAXV],int n,int e) //创建图的邻接矩阵
{
 int i,j;
 g.n=n; g.e=e;
 for (i=0;i<g.n;i++)
  for (j=0;j<g.n;j++)
   g.edges[i][j]=A[i][j];
}
void DispMat(MatGraph g) //输出邻接矩阵g
{
 int i,j;
 for (i=0;i<g.n;i++)
 {
  for (j=0;j<g.n;j++)
   if (g.edges[i][j]!=INF)
    printf("%4d",g.edges[i][j]);
   else
    printf("%4s","∞");
  printf("\n");
 }
}
//----邻接表的基本运算算法------------------------------------
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e) //创建图的邻接表
{
 int i,j;
 ArcNode *p;
 G=(AdjGraph *)malloc(sizeof(AdjGraph));
 for (i=0;i<n;i++)        //给邻接表中所有头结点的指针域置初值
  G->adjlist[i].firstarc=NULL;
 for (i=0;i<n;i++)        //检查邻接矩阵中每个元素
  for (j=n-1;j>=0;j--)
   if (A[i][j]!=0 && A[i][j]!=INF)   //存在一条边
   { p=(ArcNode *)malloc(sizeof(ArcNode)); //创建一个结点p
    p->adjvex=j;
    p->weight=A[i][j];
    p->nextarc=G->adjlist[i].firstarc; //采用头插法插入结点p
    G->adjlist[i].firstarc=p;
   }
 G->n=n; G->e=n;
}
void DispAdj(AdjGraph *G) //输出邻接表G
{
 int i;
 ArcNode *p;
 for (i=0;i<G->n;i++)
 {
  p=G->adjlist[i].firstarc;
  printf("%3d: ",i);
  while (p!=NULL)
  {
   printf("%3d[%d]→",p->adjvex,p->weight);
   p=p->nextarc;
  }
  printf("∧\n");
 }
}
void DestroyAdj(AdjGraph *&G)  //销毁图的邻接表
{ int i;
 ArcNode *pre,*p;
 for (i=0;i<G->n;i++)   //扫描所有的单链表
 { pre=G->adjlist[i].firstarc; //p指向第i个单链表的首结点
  if (pre!=NULL)
  { p=pre->nextarc;
   while (p!=NULL)   //释放第i个单链表的所有边结点
   { free(pre);
    pre=p; p=p->nextarc;
   }
   free(pre);
  }
 }
 free(G);      //释放头结点数组
}
//------------------------------------------------------------

void MatToList(MatGraph g,AdjGraph *&G)  //将邻接矩阵g转换成邻接表G
{ int i,j;
 ArcNode *p;
 G=(AdjGraph *)malloc(sizeof(AdjGraph));
 for (i=0;i<g.n;i++)    //将邻接表中所有头结点的指针域置初值
  G->adjlist[i].firstarc=NULL;
 for (i=0;i<g.n;i++)    //检查邻接矩阵中每个元素
  for (j=g.n-1;j>=0;j--)
   if (g.edges[i][j]!=0 && g.edges[i][j]!=INF) //存在一条边
   { p=(ArcNode *)malloc(sizeof(ArcNode)); //创建一个边结点p
    p->adjvex=j; p->weight= g.edges[i][j];
    p->nextarc=G->adjlist[i].firstarc;  //采用头插法插入结点p
    G->adjlist[i].firstarc=p;
   }
 G->n=g.n;G->e=g.e;
}
/*
void ListToMat(AdjGraph *G,MatGraph &g) //将邻接表G转换成邻接矩阵g
{ int i;
 ArcNode *p;
 for (i=0;i<G->n;i++)   //扫描所有的单链表
 { p=G->adjlist[i].firstarc; //p指向第i个单链表的首结点
  while (p!=NULL)    //扫描第i个单链表
  { g.edges[i][p->adjvex]=p->weight;
   p=p->nextarc;
  }
 }
 g.n=G->n;g.e=G->e;
}
*/
int main()
{
 MatGraph g;
 AdjGraph *G;
 int A[MAXV][MAXV]={{0,1,0,1,1},{1,0,1,1,0},
   {0,1,0,1,1},{1,1,1,0,1},{1,0,1,1,0}};
 int n=5, e=8;
 CreateMat(g,A,n,e);   //建立《教程》中图8.1(a)的邻接矩阵
 printf("图G的邻接矩阵:\n");
 DispMat(g);     //输出邻接矩阵g
 printf("将g转换为邻接表G\n");
 MatToList(g,G);    //输出邻接表G
 printf("图G的邻接表:\n");
 DispAdj(G);
 DestroyAdj(G);    //销毁邻接表
 /*CreateAdj(G,A,n,e);   //建立《教程》中图8.1(a)的邻接表
 printf("图G的邻接表:\n");
 DispAdj(G);     //输出邻接表G
 printf("将G转换为邻接矩阵g\n");
 ListToMat(G,g);
 DispMat(g);     //输出邻接矩阵g
 DestroyAdj(G);    //销毁邻接表*/
 return 1;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值