实验题目: 图的存储及基本操作
一、实验目的
1、掌握图的顺序存储(邻接矩阵)存储实现;
2、掌握图的顺序存储(邻接矩阵)存储体上的基本操作;
3、掌握图的邻接链表存储实现;
4、掌握图的邻接链表存储体上的基本操作;
二、实验作业
在给出部分代码的基础上完成:
1、编写图的顺序存储(邻接矩阵)的函数,实现图的顺序存储(邻接矩阵)。
2、编写函数,在图的顺序存储体上进行:
(1)某顶点的度(出度,入度)的计算;
(2)输出某顶点的邻接点(邻接到的点)。
3、编写图的邻接链表函数,实现图的邻接链表存储。
4、编写函数,在图的邻接链表存储体上进行:
(1) 某顶点的度(出度,入度)的计算;
(2) 输出某顶点的邻接点(邻接到的点)。
三、实验内容
1、
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 105
#define RST(N) memset(N, 0, sizeof(N)) //宏定义函数RST(N):使数组N清零
//memset()一般是对字符型数组赋初值,如果非要对整型数组赋初值,只能赋值0.
//原因是memset是设置每一个“字节”的值。
using namespace std;
int n, m, Edge[MAXN][MAXN]; //顶点数,有向边数,邻接矩阵;
int Mc, Md, u, v; //入度,出度,边的起点,终点;
void Init() //初始化;
{
RST(Edge); //二维数组Edge清零
for(int i=1; i<=m; i++) { //添加有向边
scanf("%d %d", &u, &v);
Edge[u-1][v-1] = 1;
printf("The %d edge is %d->%d,\n", i,u,v);
}
}
void Print_In_Degree() //输出有向图各顶点的入度;
{
printf("The degree of entry of each vertex of the digraph is: ");
for(int i=0; i<n; i++) {
Mc = 0;
for(int j=0; j<n; j++) Mc += Edge[i][j];
printf("%d", Mc);
i == n-1 ? printf("\n") : printf(" ");
}
}
void Print_Out_Degree() //输出有向边各顶点的出度;
{
printf("The degree of leaving of each vertex of the digraph is: ");
for(int i=0; i<n; i++) {
Md = 0;
for(int j=0; j<n; j++) Md += Edge[j][i];
printf("%d", Md);
i == n-1 ? printf("\n") : printf(" ");
}
}
int main()
{
freopen("实验6.1_data_in.txt", "r", stdin);
// freopen("实验6.1_data.out", "w", stdout);
// scanf("%d %d", &n, &m);
// Init();
while(~scanf("%d %d", &n, &m)) { // && n || m
printf("This Graph has %d nodes, and %d edges\n", n,m);
Init(); //从文件中读入所有的边,构造邻接矩阵
Print_In_Degree(), Print_Out_Degree();
}
fclose(stdin);
// fclose(stdout);
return 0;
}
2、
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX 1000
int array [MAX][MAX];
using namespace std;
int main(int argc, char *argv[]) {
int i,j; //循环变量
int verNum,edgeNum; //顶点数和边数
int verArray [1000][100];
int on,in; //出度和入度
int start , end; //起点,终点
while(1){
freopen("实验6.1_data_in.txt", "r", stdin);
memset(array,0,sizeof(array)); //数组初始化 函数头文件 <memory.h> or <string.h>
scanf("%d%d", &verNum, &edgeNum);
if(verNum == 0 && edgeNum == 0){
break ;
}
for(i = 0 ;i < edgeNum;i ++){
scanf("%d%d", &start, &end);
array[start - 1][end - 1] = 1;
}
for(i =0 ; i < verNum; i++){
on = 0; //按行数,表示顶点的出度
for(j = 0 ;j < verNum;j++){
if(array[i][j] == 1){
on++;
}
}
if(i == 0){
printf("%d",on); //注意输出格式判断
}else{
printf(" %d",on);
}
}
printf("\n"); //换行
for(i = 0 ; i < verNum; i++){
in = 0; //按行数,表示顶点的出度
for(j = 0 ;j < verNum;j++){
if(array[j][i] == 1){
in++;
}
}
if(i ==0 ){
printf("%d",in);
}else{
printf(" %d",in); //没有初始化时,会输出48706等奇怪数字
}
}
break;
}
return 0;
}
typedef int ElemType;
typedef struct
{
ElemType data[MaxSize];
int front,rear; //队首和队尾指针
} SqQueue;
void InitQueue(SqQueue *&q)
{ q=(SqQueue *)malloc (sizeof(SqQueue));
q->front=q->rear=0;
}
void DestroyQueue(SqQueue *&q)
{
free(q);
}
bool QueueEmpty(SqQueue *q)
{
return(q->front==q->rear);
}
bool enQueue(SqQueue *&q,ElemType e)
{ if ((q->rear+1)%MaxSize==q->front) //队满上溢出
return false;
q->rear=(q->rear+1)%MaxSize;
q->data[q->rear]=e;
return true;
}
bool deQueue(SqQueue *&q,ElemType &e)
{ if (q->front==q->rear) //队空下溢出
return false;
q->front=(q->front+1)%MaxSize;
e=q->data[q->front];
return true;
}
//---------------------------------------------------------
void BFS(AdjGraph *G,int v)
{
int w,i;
ArcNode *p;
SqQueue *qu; //定义环形队列指针
InitQueue(qu); //初始化队列
int visited[MAXV]; //定义顶点访问标志数组
for (i=0;i<G->n;i++) visited[i]=0; //访问标志数组初始化
printf("%2d",v); //输出被访问顶点的编号
visited[v]=1; //置已访问标记
enQueue(qu,v);
while (!QueueEmpty(qu)) //队不空循环
{
deQueue(qu,w); //出队一个顶点w
p=G->adjlist[w].firstarc; //指向w的第一个邻接点
while (p!=NULL) //查找w的所有邻接点
{
if (visited[p->adjvex]==0) //若当前邻接点未被访问
{
printf("%2d",p->adjvex); //访问该邻接点
visited[p->adjvex]=1; //置已访问标记
enQueue(qu,p->adjvex); //该顶点进队
}
p=p->nextarc; //找下一个邻接点
}
}
printf("\n");
}
int main()
{
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;
CreateAdj(G,A,n,e); //建立《教程》中图8.1(a)的邻接表
printf("图G的邻接表:\n");
DispAdj(G); //输出邻接表G
printf("广度优先序列:");BFS(G,2);printf("\n");
DestroyAdj(G); //销毁邻接表
return 1;
}
#include "graph.cpp"
int visited[MAXV]={0};
void DFS(AdjGraph *G,int v)
{
ArcNode *p;
visited[v]=1; //置已访问标记
printf("%d ",v); //输出被访问顶点的编号
p=G->adjlist[v].firstarc; //p指向顶点v的第一条弧的弧头结点
while (p!=NULL)
{
if (visited[p->adjvex]==0) //若p->adjvex顶点未访问,递归访问它
DFS(G,p->adjvex);
p=p->nextarc; //p指向顶点v的下一条弧的弧头结点
}
}
int main()
{
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;
CreateAdj(G,A,n,e); //建立《教程》中图8.1(a)的邻接表
printf("图G的邻接表:\n");
DispAdj(G); //输出邻接表G
printf("深度优先序列(递归):");DFS(G,2);printf("\n");
DestroyAdj(G); //销毁邻接表
return 1;
}
四、实验结果
(实验结果截图)
1.
五、实验心得
(心得体会,书写要详细、具体,包括问题及解决办法或者方法)