数据结构 图型结构的应用——无向图生成

一、实验目的

1、掌握图的基本存储方法及有关图的操作算法;

2、熟悉图和各种存储结构及其构造算法,了解实际问题的求解效率与采用何种存储结构以及算法有着密切的关系。

二、实验要求

学会邻接表的基本操作

三、实验内容

1、构造一个无向图的邻接表;

2、要求:从键盘输入图的顶点数和图的边数;并显示所构造的邻接表。

四、实验步骤

  1. 输入与构建邻接表;

遍历输出邻接表。

#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的下一个邻接点 
	} 
}

 

 

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值