邻接表
定义
邻接表 由 表头节点 和边表组成
图的链式存储结构
每个顶点建立一个单链表 , 相邻的顶点都放在这个链表
第一个结点存放点信息作为表头
其余存放边信息
1.表头结点表
以所有表头节点以顺序结构的形式存储 , 便于访问任一顶点
表头 : 数据域 和 链域
2.边表
由顶点间的2n个边链表节点组成
边链表包括 : 邻接点域 数据域 链域
邻接点域——>指示与顶点相邻的点在图的位置
数据域——>边有关信息
链域——>与顶点邻接的下一个节点
示例;
无向图中,顶点Vi的度是第i个链表的节点数
邻接表的优缺点
优点:
便于增删
便于统计边数,遍历所有边表可得边数 (n个顶点 2e个边顶点 但是只有e条边因为重复)
效率高 时间复杂度(m+e)
缺点
不便于判断顶点之间是否有边 要知道Vi是否连接Vj ,需要遍历Vi的链表
不便于计算有向图各顶点的度
无向图邻接表 :顶点 Vi的度就是第i 个边节点的个数
有向图邻接表 : i的边节点 为出度 ,入度需要全部遍历
实现
邻接表
#include<iostream>
using namespace std;
#define max 1024
int n, m;
//边节点
struct vNode{
int nodeValue;//当前结点的值
vNode* next;//下一个节点的值
vNode() {
this->next = NULL;
}
};
//头节点数组 下标对应当前顶点值
struct ListHead{
vNode* first;
}VList[1024];
/*
* 连线 v1 v2
*/
void Link(int v1, int v2) {
//在v1的表头插入v2
//采用头插法
vNode* p1 = new vNode();
p1->nodeValue = v2;
p1->next = VList[v1].first;
VList[v1].first = p1;
//在v2的表头插入v1
vNode* p2 = new vNode();
p2->nodeValue = v1;
p2->next = VList[v2].first;
VList[v2].first = p2;
}
/*
初始化
*/
void init() {
n = 5;
m = 6;
//以下n行初始化vlist
for (int i = 1; i <= n; ++i) {
VList[i].first = NULL;
}
//以下m行建图
Link(1, 2);
Link(1, 4);
Link(2, 3);
Link(2, 5);
Link(3, 4);
Link(3, 5);
}
void printLink() {
for (int i = 1; i <= n; i++) {
if (VList[i].first) {
cout << i ;
vNode* temp = VList[i].first;
while (temp) {
cout << " -> " << temp->nodeValue;
temp = temp->next;
}
cout << endl;
}
else {
cout << i<<endl;
}
}
}
int main() {
init();
printLink();
return 0;
}