(此文借鉴 dollarzhaole 的 《邻接表建图方法及代码》 )
说明:
建立有向图(稍加更改可变为无向图);
第一行输入n 表示边数;
随后n行输入a, b, c 分别表示边的起点, 终点, 权值;
输入示例:
5
3 4 6
3 7 8
1 3 6
2 4 7
3 5 1
图示例:
方法:
利用数组和结构体模拟边与边的关系, 极大的节省空间和时间;
图示解析:
代码:
1.有向图:
#include <stdio.h>
#include <string.h>
#define N 100
struct Edge{ //此结构体表示边
int start; //边起点
int end; //边终点
int weight; //权值
int next; //下一个与start有关的边
};
int first[N]; //存储以下标为起点的边的(最后)位置
Edge e[N] ; //存储边的具体信息
void Build_Graph() //建图
{
int edges; //边数
memset(first, -1, sizeof(first)); //-1表示该起点不存在连边
scanf("%d", &edges);
for(int i = 0; i < edges; i ++){
scanf("%d%d%d", &e[i].start, &e[i].end, &e[i].weight); //输入节点信息
e[i].next = first[e[i].start];
first[e[i].start] = i;
/* first数组存储的是"最新的"以下标i为起点的边在e数组中的位置, 所以有新
数据都要先修改过first, 类似单链表的头插法;
但在更改first[i]的值前, 应先修改边的next值为first[i]的当前值,犹如单
链表头插前要修改 newnode ->next = head ->next; */
}
}
void Print_Graph()
{
for(int i = 1; i < 10; i ++) //输出图 10暂且表示顶点最大值
{
if(first[i] == -1) continue; //该起点没边
printf("以%d为起点的所有边的信息:\n", i);
for(int j = first[i]; j != -1; j = e[j].next) //遍历以j为起点的所有边的信息
printf("%d %d %d\n", e[j].start, e[j].end, e[j].weight);
printf("\n");
}
}
int main()
{
Build_Graph();
Print_Graph();
return 0;
}
2.无向图:
#include <stdio.h>
#include <string.h>
#define N 100
struct Edge{ //此结构体表示边
int start; //边起点
int end; //边终点
int weight; //权值
int next; //下一个与start有关的边
};
int first[N]; //存储以下标为起点的边的(最后)位置
Edge e[N] ; //存储边的具体信息
void Build_Graph() //建图
{
int edges; //边数(关系数)
memset(first, -1, sizeof(first)); //-1表示该起点不存在连边
scanf("%d", &edges);
for(int i = 0; i < edges * 2; i ++){
scanf("%d%d%d", &e[i].start, &e[i].end, &e[i].weight); //输入节点信息
e[i].next = first[e[i].start];
first[e[i].start] = i;
i ++; //无向图增加代码
e[i].start = e[i - 1].end;
e[i].end = e[i - 1].start;
e[i].weight = e[i - 1].weight;
e[i].next = first[e[i].start];
first[e[i].start] = i;
/* first数组存储的是"最新的"以下标i为起点的边在e数组中的位置, 所以有新
数据都要先修改过first, 类似单链表的头插法;
但在更改first[i]的值前, 应先修改边的next值为first[i]的当前值,犹如单
链表头插前要修改 newnode ->next = head ->next; */
}
}
void Print_Graph()
{
for(int i = 1; i < 10; i ++) //输出图 10暂且表示顶点最大值
{
if(first[i] == -1) continue; //该起点没边
printf("以%d为起点的所有边的信息:\n", i);
for(int j = first[i]; j != -1; j = e[j].next) //遍历以j为起点的所有边的信息
printf("%d %d %d\n", e[j].start, e[j].end, e[j].weight);
printf("\n");
}
}
int main()
{
Build_Graph();
Print_Graph();
return 0;
}