无向图的表示:邻接矩阵和邻接表

这里将一个无向图用邻接表和邻接矩阵表示。

输入:顶底个数n,图中的各个边(用两个顶点表示)。

输出:这个无线图的邻接矩阵和邻接表,其中邻接表中的链接按元素大小升序排列。

先给出一个例子说明。假设有无向图如下,则其邻接矩阵和邻接表如提示框中所示(其实就是下面程序的输出)。


下面是程序的代码:

#include <stdio.h>
#include <stdlib.h>

//图的表示,输入节点个数和边,构造图的邻接矩阵和邻接表

//邻接表中的链表节点
struct vNode{
	int value;
	struct vNode* next;
};

//向邻接表中插入一个数据,并保证邻接表的有序性
void insertIntoAdjVertics(struct vNode** adjVertics,int start,int end){
	
	struct vNode* node = (struct vNode*)malloc(sizeof(struct vNode));
	struct vNode* head = adjVertics[start];

	node->value = end;
	node->next = NULL;

	if(head == NULL){
		adjVertics[start] = node;
		return;
	}

	if(head->next==NULL&&head->value>end){
		node->next = head;
		adjVertics[start] = node;
		return;
	}

	while(head->next!=NULL && head->next->value<end){
		head = head->next;
	}
	
	if(head->next==NULL){
		head->next = node;
		return;
	}

	node->next = head->next;
	head->next = node;
}

//打印邻接矩阵
void displayNeighborMatrix(int** neighborMatrix,int n){
	int i,j;

	printf("\n");
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			printf("%d ",neighborMatrix[i][j]);
		}
		printf("\n");
	}
}

//打印邻接表
void displayAdjVertice(struct vNode** adjVertics,int n){
	int i;
	for(i=0;i<n;i++){
		struct vNode* head = adjVertics[i];
		printf("%d: ",i);
		while(head!=NULL){
			printf("->%d ",head->value);
			head = head->next;
		}
		
		printf("\n");
	}
}


int main() {
	int n,i,j;
	int** neighborMatrix;
	struct vNode** adjVertics;
	int start,end;

	printf("input vertex number: ");
	scanf("%d",&n);

	//初始化邻接矩阵
	neighborMatrix = (int**)malloc(sizeof(int*)*n);
	for(i=0;i<n;i++){
		neighborMatrix[i] = (int*)malloc(sizeof(int)*n);
		for(j=0;j<n;j++){
			neighborMatrix[i][j] = 0;
		}
	}
	
	adjVertics = (struct vNode**)malloc(sizeof(struct vNode*)*n);
	for(i=0;i<n;i++){
		adjVertics[i] = NULL;
	}
	
	//输入定点,格式为 1 2
	printf("input start and end vertex, format 1 2, stop by -1. \n");
	
	while(1){
		scanf("%d",&start);
		if(start==-1){
			break;
		}
		scanf("%d",&end);

		neighborMatrix[start][end] = 1;		//对称矩阵
		neighborMatrix[end][start] = 1;
		insertIntoAdjVertics(adjVertics,start,end);
		insertIntoAdjVertics(adjVertics,end,start);
	}

	displayNeighborMatrix(neighborMatrix,n);
	printf("-------------\n");
	displayAdjVertice(adjVertics,n);

	return EXIT_SUCCESS;
}


  • 13
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 无向图邻接矩阵表示可以转换为邻接表表示,具体步骤如下: 1. 创建一个空的邻接表,其中包含与无向图中每个顶点对应的链表。 2. 对于邻接矩阵中的每个元素a[i][j],如果其值为1,则将顶点i和顶点j加入彼此的链表中。 3. 最终得到的邻接表表示即为所求。 需要注意的是,由于无向图邻接矩阵是对称的,因此在转换为邻接表时,需要将每个顶点的链表中的元素去重,以避免重复计算。 ### 回答2: 无向图是指图中的每个边都没有方向属性。邻接矩阵是一种常用的图的表示方式,主要针对稠密图,邻接表则适用于稀疏图。因此,将无向图邻接矩阵转换为邻接表是一种很常用的操作。 转换方法: 1. 创建一个链表数组,数组的大小等于顶点的数量。 2. 对于邻接矩阵中的每个非零元素matrix[i][j],将其添加到链表数组的第i位和第j位两个链表中。例如,如果matrix[2][4]非零,则将(4,2)添加到链表数组的第4位和第2位两个链表中。 3. 邻接表中的每个链表可以排序,这样它们的顺序就不会影响算法的结果。我们可以将链表中的所有节点按照从小到大排序,以在需要遍历它们时方便执行。 4. 这样就完成了邻接矩阵转换为邻接表的操作。 比较邻接矩阵邻接表: 1. 空间复杂度:邻接矩阵需要 $O(n^2)$ 的空间,而邻接表只需要 $O(n+m)$ 的空间,其中 $m$ 是边的数量。 2. 时间复杂度:邻接矩阵在查找两个顶点之间是否有边时需要 $O(1)$ 的时间,而邻接表中需要遍历链表,时间复杂度为 $O(degree(v_i))$,其中 $degree(v_i)$ 是顶点 $v_i$ 的度数,即与顶点 $v_i$ 相邻的边数。 因此,对于稠密图,邻接矩阵是更好的选择。而对于稀疏图,邻接表更加适用。在实际应用中,需要根据具体情况选择适合的表示方法。 ### 回答3: 无向图是一种没有方向的图,其中的节点会相互连通。无向图最常见的两种表示方法是邻接矩阵邻接表邻接矩阵是一种二维数组,其中每个元素a[i][j]代表节点i和节点j之间的连通情况,如果a[i][j]的值为1,表示节点i和节点j连通;如果a[i][j]的值为0,表示节点i和节点j不连通。当然,邻接矩阵也可以表示权重图,此时a[i][j]的值为两个节点之间的边权值。无向图邻接矩阵是一个对称矩阵。 邻接表是一种链表结构,其中每个节点都维护一个与其直接相连的节点列表。对于每个节点i,它的邻接表中包含了所有和节点i相连的节点号。在邻接表中,每个节点和它的邻居都变成了一条边,每个节点在邻接表中出现一次。邻接表的优点是可以很方便地找到一个节点的所有邻居节点,而且适用于稀疏图。 要将一个无向图邻接矩阵转换为邻接表,可以按行遍历邻接矩阵。对于每一行i,找出里面值为1的元素的列号,然后将i节点和这些列号对应的节点连成边,最终得到i节点的邻接表。重复以上操作,可以得到整个无向图邻接表。 对于邻接矩阵中每个元素a[i][j],其值为1时,需要将节点i和节点j连成一条边。由于在无向图中,节点i和节点j之间的边是无方向的,因此需要将两个节点之间连成双向边。也就是说,可以将i节点的邻接表中加入j节点,同时将j节点的邻接表中加入i节点。 总之,无向图邻接矩阵可以通过按行遍历的方式转换为邻接表邻接表可以更好地表示稀疏图,并且可以方便地查找一个节点的所有邻居节点。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值