一、实验目的
- 学习图的基本定义方式
- 熟练掌握图的矩阵存储和邻接表存储。
二、实验要求
【项目1】实现图的邻接矩阵和邻接表的存储,要求:
- 建立如图所示的有向图G的邻接矩阵,并输出;
- 建立如图所示的有向图G的邻接表,并输出。
main.cpp程序代码:
#include <iostream>
#include <stdio.h>
#include "graph.h"
using namespace std;
int main()
{
int a[6][MAXV] = {{0,5,INF,7,INF,INF},
{INF,0,4,INF,INF,INF},
{8,INF,0,INF,INF,9},
{INF,INF,5,0,INF,6},
{INF,INF,INF,5,0,INF},
{3,INF,INF,INF,1,0}};
MatGraph *graph;
createMat(graph,a,6,10);
cout<<"*********显示邻接矩阵*********"<<endl;
dispMat(graph);
destroyMat(graph);
cout<<endl;
AdjGraph *G;
createAdj(G,a,6,10);
// MatToList1(graph,G);
cout<<"*********显示邻接表*********"<<endl;
dispAdj(G);
destroyAdj(G);
return 0;
}
运行结果截图:
【项目2】—项目1的图采用邻接矩阵 g 存储,设计实现以下功能的算法:
(1)求出图中每个顶点的入度。
(2)求出图中每个顶点的出度。
程序代码:
Main.cpp:
#include <iostream>
#include <stdio.h>
#include "graph.h"
using namespace std;
int main()
{
int a[6][MAXV] = {{0,5,INF,7,INF,INF},
{INF,0,4,INF,INF,INF},
{8,INF,0,INF,INF,9},
{INF,INF,5,0,INF,6},
{INF,INF,INF,5,0,INF},
{3,INF,INF,INF,1,0}};
MatGraph *graph;
createMat(graph,a,6,10);
cout<<"*********显示邻接矩阵*********"<<endl;
dispMat(graph);
countOutMat(graph);
countInMat(graph);
destroyMat(graph);
return 0;
}
Graph.cpp:
#include "graph.h"
#include <iostream>
using namespace std;
//邻接表相关函数定义
void createAdj(AdjGraph *& graph,int a[MAXV][MAXV],int n,int e)//创建邻接表
{
ArcNode * arcnode;
graph = (AdjGraph*)malloc(sizeof(AdjGraph*));
for(int i = 0;i<n;++i){
graph->adjlist[i].firstarc = NULL; //初始状态下,头结点不指向任何结点
}
for(int i = 0;i < n; ++i){ //扫描邻接矩阵中的所有顶点
for(int j = n-1 ;j>=0;--j){
if(a[i][j] != 0 && a[i][j] != INF){
arcnode = (ArcNode*)malloc(sizeof(ArcNode*));
arcnode->adjvex = j;
arcnode->weight = a[i][j];
arcnode->nextarc = graph->adjlist[i].firstarc; //头插法插入节点
graph->adjlist[i].firstarc = arcnode;
}
}
}
graph->n = n;
graph->e = e;
}
void dispAdj(AdjGraph *graph)//显示邻接表
{
ArcNode* arcnode;
for(int i = 0;i < graph->n;++i){
arcnode = graph->adjlist[i].firstarc;
printf("%3d: ",i);
while(arcnode != NULL){
printf("%3d[%d]->",arcnode->adjvex,arcnode->weight);
arcnode = arcnode -> nextarc;
}
printf("^\n");
}
}
void destroyAdj(AdjGraph* graph)
{
ArcNode* arcnode,*p;
for(int i = 0;i < graph->n;++i){
arcnode = graph->adjlist[i].firstarc;
if(arcnode != NULL){
p = arcnode->nextarc;
while(p != NULL){
free(arcnode);
arcnode = p;
p = p->nextarc;
}
free(arcnode);
}
}
free(graph);
cout<<"*****邻接表已销毁*******"<<endl;
}
//邻接矩阵相关函数定义
void createMat(MatGraph*& graph,int a[MAXV][MAXV],int n,int e)//创建邻接矩阵
{
VertexType* vertex;
graph = (MatGraph*)malloc(sizeof(MatGraph));
for(int i = 0; i < n; ++i){
vertex = (VertexType*)malloc(sizeof(VertexType));
vertex->no = i;
for(int j = 0; j < n; ++j){
graph->edges[i][j] = a[i][j];
}
graph-> vexs[i] = *vertex;
graph->n = n;
graph->e = e;
}
}
void dispMat(MatGraph *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("%3s","∞");
else
printf("%3d",g->edges[i][j]);
printf("\n");
}
}
void destroyMat(MatGraph *g)
{
// for(int i = 0; i < g->n; ++i)
// free(g->vexs[i])
free(g);
cout<<"*****邻接矩阵已销毁*******"<<endl;
}
void MatToList1(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 countOutMat(MatGraph *g)
{
int i,j;
for(i=0;i<g->n;++i)
{
int cnt=0;
for(j=0;j<g->n;++j)
{
if(g->edges[i][j] != 0 && g->edges[i][j] != INF)
++cnt;
}
printf("第%d个顶点的出度为:%d\n",i,cnt);
}
}
void countInMat(MatGraph *g)
{
int i,j;
for(j=0;j<g->n;++j)
{
int cnt=0;
for(i=0;i<g->n;++i)
{
if(g->edges[i][j] != 0 && g->edges[i][j] != INF)
++cnt;
}
printf("第%d个顶点的入度为:%d\n",i,cnt);
}
}
Graph.h:
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include <malloc.h>
#include <stdio.h>
#include <iostream>
#define MAXV 100
#define INF 32767
using namespace std;
typedef int InfoType;
//数据结构定义
//邻接表结构定义
typedef struct ANode{
int adjvex;
struct ANode *nextarc;
int weight;
}ArcNode;//边节点类型
typedef struct Vnode{
InfoType info;
ArcNode *firstarc;
}VNode;//头节点
typedef struct {
VNode adjlist[MAXV];
int n,e;
}AdjGraph; //完整邻接表结构
//邻接矩阵结构定义
typedef struct{
int no;
InfoType info;
}VertexType; //顶点类型
typedef struct{
int edges[MAXV][MAXV];
int n,e;
VertexType vexs[MAXV];
}MatGraph; //完整邻接矩阵结构
//函数声明
//邻接表相关函数声明
void createAdj(AdjGraph *& graph,int a[MAXV][MAXV],int n,int e);
void dispAdj(AdjGraph *graph);
void destroyAdj(AdjGraph* graph);
//邻接矩阵相关函数声明
void createMat(MatGraph*& graph,int a[MAXV][MAXV],int n,int e);
void dispMat(MatGraph *g);
void destroyMat(MatGraph *g);
//邻接表和邻接矩阵相互转换
void MatToList1(MatGraph *g,AdjGraph *&G);
void countOutMat(MatGraph *g);
void countInMat(MatGraph *g);
#endif // GRAPH_H_INCLUDED
运行结果截图: