一、实验目的
1、掌握图的基本存储方法及有关图的操作算法;
2、熟悉图和各种存储结构及其构造算法,了解实际问题的求解效率与采用何种存储结构以及算法有着密切的关系。
二、实验要求
学会邻接表的基本操作。
三、实验内容
1、构造一个无向图的邻接表;
2、要求:从键盘输入图的顶点数和图的边数;并显示所构造的邻接表。
四、实验步骤
- 输入与构建邻接表;
遍历输出邻接表。
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
#define INF 100000
char arr[100];
typedef struct EdgeNode //边节点类型
{
int adj_Edge; //邻接点的编号
struct EdgeNode *next_arc; //下一条边的指针
int weight; //该边的权值,可添加其他信息
}EdgeNode;
typedef struct HeadNode //头结点类型
{
int data; //头结点的其他信息,可自由添加
EdgeNode *first_Node;//指向第一个边节点
}HeadNode;
typedef struct
{
HeadNode adj_list[MaxSize];//头节点数组
int n,e; //图的顶点数和边数
}AdjGraph;
void Create_Graph(AdjGraph *&G,int A[MaxSize][MaxSize],int n,int e);
void Display_Graph(AdjGraph *G);
void DFS(AdjGraph *G,int v);
int main()
{
int A[MaxSize][MaxSize]={{0}};
AdjGraph *G;
int n = 5,e = 5;
printf("节点数(n),边数(m):");
scanf("%d %d",&n,&e);
for(int i=0;i<n;i++)
{
printf("第%d个节点的信息:",i+1);
scanf("%s",&arr[i]);
}
for(int i=0;i<e;i++)
{
int temp_n,temp_m;
printf("第%d条边=》起点,终点:",i+1);
scanf("%d %d",&temp_n,&temp_m);
A[temp_n-1][temp_m-1]=arr[temp_n-1];
A[temp_m-1][temp_n-1]=arr[temp_m-1];
}
Create_Graph(G,A,n,e);
printf("图的邻接表表示如下:\n");
Display_Graph(G);
}
void Create_Graph(AdjGraph *&G,int A[MaxSize][MaxSize],int n,int e)//图的创建
{
EdgeNode *p;
G = (AdjGraph *)malloc(sizeof(AdjGraph));
for(int i = 0;i < n;i++) //为邻接表中所有头结点的指针域置初值
{
G->adj_list[i].first_Node = 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) //存在一条边
{
p = (EdgeNode *)malloc(sizeof(EdgeNode));
p->adj_Edge = j;
p->weight = A[i][j];
p->next_arc = G->adj_list[i].first_Node; //采用头插法插入节点p
G->adj_list[i].first_Node = p;
}
}
}
G->n = n;
G->e = e;
}
void Display_Graph(AdjGraph *G) //输出图
{
EdgeNode *p;
for(int i = 0; i < G->n; i++)
{
p = G->adj_list[i].first_Node;
printf("[%d,%c]=>", i + 1, arr[i]);
// 先将链表中的每个节点保存到一个数组中
EdgeNode *edges[MaxSize];
int count = 0;
while(p != NULL)
{
edges[count] = p;
p = p->next_arc;
count++;
}
// 倒序输出数组中的节点
for(int j = count - 1; j >= 0; j--)
{
p = edges[j];
printf("<%d,%c>->", p->adj_Edge + 1, arr[p->adj_Edge]);
}
printf("^\n");
}
}
int visited[MaxSize] = {0};//visited全局数组,用来标记顶点是否被访问,初始为 0,表示所有顶点均未被访问
void DFS(AdjGraph *G,int v)
{
EdgeNode *p;
visited[v] = 1;//从顶点v开始,标记为已访问
printf("%d ",v);
p = G->adj_list[v].first_Node;//指向v的第一个邻接点
while(p != NULL)
{
if(visited[p->adj_Edge] == 0)//第一个邻接点未被访问
DFS(G,p->adj_Edge);
p = p->next_arc; //p指向v的下一个邻接点
}
}