1. 在学习图的存储方式中,邻接矩阵和邻接表是两种比较常用的存储图的方式,下面使用的是C语言实现的邻接表
2. 具体的实现过程如下:
① 首先使用结构体声明图的结构体,图中顶点的结构体,以及指向下一条边的结构体,这些可以参照严蔚敏版的数据结构来写出具体的数据结构:
typedef struct ArcNode{
int adjvex;//该边所指向的节点的位置
struct ArcNode *nextarc;
// 边的信息, 例如边的权重
int info;
}ArcNode;
typedef struct{
//顶点表存储当前顶点的信息
int data;
//指向边的指针
ArcNode *firstarc;
}Vnode;
typedef struct{
//顶点数组
Vnode adjlist[maxSize];
//图中的顶点的数目和边的数目
int n, e;
}AGraph
② 有了这些结构体之后那么我们需要声明一个指向图的一个指针,并且使用malloc函数为图分配内存空间,假如不分配的话那么在初始化顶点的第一条边的时候会出现错误,这个是与Java语言的不同的点
③ 在一开始的时候需要对链表的第一个顶点指向的第一条边的指针进行赋值,赋值为NULL,这个是必不可少的步骤,假如没有程序就会出现错误
④ 因为这里存储的是有向有权图,所以在控制台中需要输入顶点的数目,边的数目,和边的权重,新建一个新的ArcNode节点,
将节点的adjvex赋值为v,指向下一条边的指针赋值为NULL输入之后判断图中的起始顶点指向的第一条边的指针是否为空假如为空那么将当前顶点的firstarc指针指向这个节点加入不为空那么调用插入到链表中的insertNode方法,遍历链表将节点插入到链表的最后面
⑤ 创建好了邻接表之后那么我们就可以来遍历图了,循环遍历顶点数组,判断当前顶点的下标对应的firstarc是否为空来进行遍历,为空说明当前顶点是没有出度的,有边的话那么我们需要使用while循环来遍历整个顶点链表
我感觉最重要的是要理解其中的数据结构每个元素表达的意思还有就是注意C语言中的指针在初始化的时候要为NULL否则会出现错误
测试数据如下:
3. 下面是具体的代码:
#include<stdio.h>
#include<iostream>
#include<malloc.h>
#define maxSize 1000
using namespace std;
typedef struct ArcNode{
int adjvex;
struct ArcNode *nextarc;
int info;
}ArcNode;
typedef struct{
int data;
ArcNode *firstarc;
}Vnode;
typedef struct{
Vnode adjlist[maxSize];
int n, e;
}AGraph;
AGraph *graph;
void insertNode(ArcNode *node, ArcNode *newNode){
ArcNode *p = node;
while(p->nextarc != NULL){
p = p->nextarc;
}
p->nextarc = newNode;
}
void create(){
graph = (AGraph*)malloc(sizeof(AGraph));
cout << "输入顶点的数目: " << endl;
cin >> graph->n;
cout << "输入图中边的数目: " << endl;
cin >> graph->e;
cout << graph->n << " ";
int u = -1, v = -1, weight = -1;
for(int i = 0; i < graph->n; i++){
graph->adjlist[i].firstarc = NULL;
}
ArcNode *node;
cout << graph->e << endl;
for(int i = 0; i < graph->e; i++){
cin >> u >> v >> weight;
node = (ArcNode *)malloc(sizeof(ArcNode));
node->adjvex = v;
node->info = weight;
node->nextarc = NULL;
graph->adjlist[u].data = u;
if(graph->adjlist[u].firstarc == NULL){
//边
graph->adjlist[u].firstarc = node;
}else{
//插入边
insertNode(graph->adjlist[u].firstarc, node);
}
}
}
void travseTree(){
for(int i = 0; i < graph->n; i++){
if(graph->adjlist[i].firstarc != NULL){
cout << i << " ";
ArcNode *p = graph->adjlist[i].firstarc;
while(p != NULL){
cout << p->adjvex << " ";
p = p->nextarc;
}
cout << endl;
}
}
}
int main(void){
create();
travseTree();
return 0;
}