数据结构实验六 图的操作实现
一、实验目的
1、 理解图的存储结构与基本操作;
2、 掌握图的创建过程
二、实验内容
1.根据下图,采用邻接矩阵的存储结构保存此图,并打印出邻接矩阵。
图的创建代码参考教材.
提示:首先根据给出的图结构得出该图的顶点集和边集,调用相应的函数生成图的邻接矩阵,并打印出邻接矩阵
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct
{
char list[100];
int size;
}SequenceList;
int ListInitiate(SequenceList *L)
{
L->size = 0;
}
int ListInsert(SequenceList *L,int i, char x)
{
int j;
if(L->size >= 100)
{
printf("顺序表已满\n");
return 0;
}
else if (i<0 || i>L->size)
{
printf("不合法");
return 0;
}
else
{
for(j=L->size;j>i;j--)
L->list[j]=L->list[j-1];
L->list[i]=x;
L->size ++;
return 1;
}
}
int ListLength(SequenceList L)
{
return L.size;
}
typedef struct
{
SequenceList Vertices;
int edge[100][100];
int numOfEdges;
int numVertexes;
}MatrixGraph;
void Initiate(MatrixGraph *G,int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
G->edge[i][j]=0;
}
}
G->numOfEdges=0;
ListInitiate(&G->Vertices) ;
}
void InsertVertex(MatrixGraph *G,int vertex)
{
ListInsert(&G->Vertices,G->Vertices.size,vertex);
G->numVertexes++;
}
void InsertEdge(MatrixGraph *G,int v1,int v2)
{
if(v1<0||v1>=G->Vertices.size||v2<0||v2>=G->Vertices.size)
{
printf("参数错误");
exit(1);
}
G->edge[v1][v2]=1;
G->edge[v2][v1]=1;
G->numOfEdges++;
}
typedef struct
{
int row;
int col;
} rowcol;
void CreatGraph(MatrixGraph *G,char V[],int n,rowcol E[],int e)
{
int i,k;
Initiate(G,n);
for(i=0;i<n;i++) InsertVertex(G,V[i]);
for(k=0;k<e;k++) InsertEdge(G,E[k].row,E[k].col);
}
int main(void)
{
MatrixGraph g1;
char a[]={'1','2','3','4','5'};
rowcol rc[]={{0,1},{0,2},{0,3},{0,4},{2,4},{1,3}};
int n=5,e=6;
int i,j;
CreatGraph(&g1,a,n,rc,e);
for(i=0;i<g1.Vertices.size;i++)
printf("%c ",g1.Vertices.list[i]);
printf("\n");
printf("juzhengwei\n");
for(i=0;i<g1.Vertices.size;i++)
{
for(j=0;j<g1.Vertices.size;j++)
printf("%5d ",g1.edge[i][j]);
printf("\n");
}
return 0;
}
2.根据上一题的邻接矩阵,编程实现该图的深度与广度优先遍历算法,从顶点1开始遍历,分别输出深度与广度优先遍历序列。
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct
{
char list[100];
int size;
}SequenceList;
int ListInitiate(SequenceList *L)
{
L->size = 0;
}
int ListInsert(SequenceList *L,int i, char x)
{
int j;
if(L->size >= 100)
{
printf("顺序表已满\n");
return 0;
}
else if (i<0 || i>L->size)
{
printf("不合法");
return 0;
}
else
{
for(j=L->size;j>i;j--)
L->list[j]=L->list[j-1];
L->list[i]=x;
L->size ++;
return 1;
}
}
int ListLength(SequenceList L)
{
return L.size;
}
typedef struct
{
SequenceList Vertices;
int edge[100][100];
int numOfEdges;
int numVertexes;
}MatrixGraph;
void Initiate(MatrixGraph *G,int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
G->edge[i][j]=0;
}
}
G->numOfEdges=0;
G->numVertexes=0;
ListInitiate(&G->Vertices) ;
}
void InsertVertex(MatrixGraph *G,int vertex)
{
ListInsert(&G->Vertices,G->Vertices.size,vertex);
G->numVertexes++;
}
void InsertEdge(MatrixGraph *G,int v1,int v2)
{
if(v1<0||v1>=G->Vertices.size||v2<0||v2>=G->Vertices.size)
{
printf("参数错误");
exit(1);
}
G->edge[v1][v2]=1;
G->edge[v2][v1]=1;
G->numOfEdges++;
}
typedef struct
{
int row;
int col;
} rowcol;
void CreatGraph(MatrixGraph *G,char V[],int n,rowcol E[],int e)
{
int i,k;
Initiate(G,n);
for(i=0;i<n;i++) InsertVertex(G,V[i]);
for(k=0;k<e;k++) InsertEdge(G,E[k].row,E[k].col);
}
typedef struct QNode //结点结构
{
int data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct //队列的链表结构
{
QueuePtr front,rear;//队头、队尾指针
}LinkQueue;
//初始化队列:
int initQueue(LinkQueue *q)
{
q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
if(!q->front)
return 0;
q->front->next = NULL;
return 1;
}
//入队:插入元素e为q的新的队尾元素
int EnQueue(LinkQueue *q,int e)
{
QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
if(!s)//存储分配失败
return 0;
s->data = e;
s->next = NULL;
q->rear->next = s;
q->rear = s;
return 1;
}
//出队
//若队列不为空,删除q的队头元素,用e返回其值,并返回OK,否则返回ERROR
int DeQueue(LinkQueue *q,int *e)
{
QueuePtr p;
if(q->front==q->rear)
return 0;
p = q->front->next;
*e = p->data;
q->front->next = p->next;
if(q->rear==p)//若队头是队尾,则删除后将rear指向头结点
q->rear = q->front;
free(p);
return 1;
}
//判断是否为空队列,若为空队列则返回1,否则返回0
int QueueEmpty(LinkQueue q)
{
if(q.front == q.rear)
return 1;
return 0;
}
int visited[100];//判断访问
void DFS(MatrixGraph G,int i)
{
int j;
visited[i] = 1;
printf("%c ",G.Vertices.list[i]);
for(j=0;j<G.numVertexes;j++)
if(G.edge[i][j]==1 && !visited[j])
DFS(G,j);//对未访问的邻接顶点递归调用
}
//邻接矩阵的深度遍历算法
void DFSTraverse(MatrixGraph G)
{
int i;
for(i=0;i<G.numVertexes;i++)
visited[i]=0;//初始所有顶点状态都是未被访问过
for(i=0;i<G.numVertexes;i++)
if(!visited[i])
DFS(G,i);
}
//邻接矩阵的广度遍历算法
void BFSTraverse(MatrixGraph G)
{
int i,j;
LinkQueue Q;
for(i=0;i<G.numVertexes;i++)
{
visited[i] = 0;
}
initQueue(&Q);
for(i=0;i<G.numVertexes;i++)
{
if(!visited[i])
{
visited[i] = 1;
printf("%c ",G.Vertices.list[i]);
EnQueue(&Q,i);
while(!QueueEmpty(Q))//若当前顶点不为空
{
DeQueue(&Q,&i); //将队中元素出队列,赋值给i
for(j=0;j<G.numVertexes;j++)
{
if(G.edge[i][j] ==1 && !visited[j])
{
visited[j] = 1;//将找到的此顶点标记为已访问
printf("%c ",G.Vertices.list[j]);
EnQueue(&Q,j);//将找到的此顶点入队列
}
}
}
}
}
}
int main(void)
{
MatrixGraph g1;
char a[]={'1','2','3','4','5'};
rowcol rc[]={{0,1},{0,2},{0,3},{0,4},{2,4},{1,3}};
int n=5,e=6;
int i,j;
CreatGraph(&g1,a,n,rc,e);
for(i=0;i<g1.Vertices.size;i++)
printf("%c ",g1.Vertices.list[i]);
printf("\n");
printf("DFS:");
DFSTraverse(g1);
printf("BFS:");
BFSTraverse(g1);
return 0;
}