【转】图的邻接链表 adjacent list of graph

简介:

1. 邻接表的结点结构
边结点结构
     邻接表中每个表结点均有两个域:
① 邻接点域adjvex
存放与vi相邻接的顶点vj的序号j。
② 链域next
将邻接表的所有表结点链在一起。
注意:
    如果带权图,则在表结点中还应增加一个保存权值等相关信息info。

2.邻接表的表示
     对于无向图,vi的邻接表中每个表结点都对应于与vi相关联的一条边。因此,将邻接表的表头向量称为顶点表。将无向图的邻接表称为边表。
注意:
    n个顶点e条边的无向图的邻接表表示中有n个顶点表结点和2e个边表结点。
     对于有向图,vi的邻接表中每个表结点都对应于以vi为始点射出的一条边。因此,将有向图的邻接表称为出边表。
注意:
    n个顶点e条边的有向图,它的邻接表表示中有n个顶点表结点和e个边表结点。

4.有向图的逆邻接表
    在有向图中,为图中每个顶点vi建立一个入边表的方法称逆邻接表表示法。
    入边表中的每个表结点均对应一条以vi为终点(即射入vi)的边。
【例】

注意:
     n个顶点e条边的有向图,它的接表表示中有n个顶点表结点和e个边表结点。

邻接链表表示的图类 
const int MaxVertices=100;
typedef int VerT;
typedef int DistT;
struct Edge{ int dest; //邻接顶点下标
                DistT weight; //边的权值,或更多
                Edge *next; //指针
             };
struct item { VerT data;       //顶点数据
                Edge *adj;     //邻接边的指针
             };
item Vertices[MaxVertices];       //顶点的数组 

建立一个无向图的邻接链表:
void AdjTWGraph::CreatG(int n,int e)
{ int vi,vj; DistT w;
numE=e; numV=n;
cout<<"\n 输入顶点的信息(整型):" ;
for (int i=1; i<=numV; i++ ) { cout<<"\n "<<i<<": ";
cin>>Vertices[i].data;
}
for ( int i=1; i<=numE; i++ )
{ cout<<"\n 输入边的信息(顶点号vi 顶点号vj 边的权值W):";
cin>>vi>>vj>>w;
//---------------------- 在第vi条链表上,链入边(vi,vj)的结点
Edge *q=new Edge;
q->dest=vj; q->weight=w; q->next=NULL; 
//vj是vi的邻接顶点,w是权值
if(Vertices[vi].adj==NULL) Vertices[vi].adj=q;           //第一次插入
else            //非第一次插入
{ Edge *curr=Vertices[vi].adj, *pre=NULL;
while (curr!=NULL && curr->dest<vj )
{ pre=curr; curr=curr->next; }
if ( pre==NULL )           //在第一个结点前插入
{ q->next=Vertices[vi].adj; Vertices[vi].adj=q; }
else {q->next=pre->next;           //在其他位置插入
pre->next=q;
}
}
//-------------------在第vj条链表上,链入边(vj,vi)的结点
Edge *p=new Edge;
p->dest=vi; p->weight=w; p->next=NULL;
if(Vertices[vj].adj==NULL) Vertices[vj].adj=p;           //第一次插入
else            //非第一次插入
{ Edge *curr=Vertices[vj].adj, *pre=NULL;
while (curr!=NULL && curr->dest<vi )
{ pre=curr; curr=curr->next; }
if ( pre==NULL )           //在第一个结点前插入
{ p->next=Vertices[vj].adj; Vertices[vj].adj=p; }
else { p->next=pre->next;           //在其他位置插入
pre->next=p;
}
}
}       //for ( int i=1; i<=numE; i++ )
}            //函数结束
      该算法的时间复杂度是 O(n+2e) ,在上述算法中去掉黑体部分语句,就是有向图的建立算法,其时间复杂度为 O(n+e) 

本文转自博客园知识天地的博客,原文链接:【转】图的邻接链表 adjacent list of graph,如需转载请自行联系原博主。

相关文章
|
4月前
|
存储 C++
C++的list-map链表与映射表
```markdown C++ 中的`list`和`map`提供链表和映射表功能。`list`是双向链表,支持头尾插入删除(`push_front/push_back/pop_front/pop_back`),迭代器遍历及任意位置插入删除。`map`是键值对集合,自动按键排序,支持直接通过键来添加、修改和删除元素。两者均能使用范围for循环遍历,`map`的`count`函数用于统计键值出现次数。 ```
|
5月前
|
存储 C++
C++的list-map链表与映射表
这篇教程介绍了C++中`list`链表和`map`映射表的基本使用。`list`链表可通过`push_front()`、`push_back()`、`pop_front()`和`pop_back()`进行元素的添加和删除,使用迭代器遍历并支持在任意位置插入或删除元素。`map`是一个键值对的集合,元素自动按键值排序,可使用下标操作符或`insert()`函数插入元素,通过迭代器遍历并修改键值对,同时提供`count()`方法统计键值出现次数。教程中包含多个示例代码以帮助理解和学习。
|
5月前
|
C++ 容器
【C++进阶】深入STL之list:高效双向链表的使用技巧
【C++进阶】深入STL之list:高效双向链表的使用技巧
59 0
|
5月前
|
存储 NoSQL Redis
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding
|
6月前
|
存储 Python
链表(Linked List)详解
链表(Linked List)详解
50 0
|
6月前
|
测试技术 C语言
如何用C语言实现无头单向非循环链表Single List ?
这篇文档介绍了一个关于单链表数据结构的实现和相关操作。单链表是一种线性数据结构,每个元素(节点)包含数据和指向下一个节点的指针。文档中列出了单链表的图示,并提供了C语言实现单链表的代码,包括动态申请节点、打印链表、头插、尾插、头删、尾删、查找和在特定位置插入或删除节点等函数。 此外,文档还包含了三个测试用例(TestSList1至TestSList4),展示了如何使用这些函数创建、修改和操作单链表。这些测试用例涵盖了插入、删除、查找等基本操作,以及在链表中特定位置插入和删除节点的场景。
41 0
|
6月前
|
存储 算法 Linux
【C/C++ 线性表】C++ 从零开始实现 双向循环链表(Exploring Doubly Circular Linked List in C++)
【C/C++ 线性表】C++ 从零开始实现 双向循环链表(Exploring Doubly Circular Linked List in C++)
120 0
|
6月前
|
应用服务中间件 nginx
Nginx源码阅读:ngx_list_t 链表
Nginx源码阅读:ngx_list_t 链表
91 0
|
6月前
|
大数据 Java 程序员
「LeetCode合集」链表(List)及经典问题
「LeetCode合集」链表(List)及经典问题
51 0
Streamのlist链表转换
Streamのlist链表转换
64 0