邻接多重表
上一节总结了有向图的另外一种链式存储结构—十字链表,该节继续总结无向图的另一种链式存储结构。
基本概念
邻接表虽然已经能够很好地表示无向图了,但是无向图访问或者删除一条边(Vi,Vj)时需要同时访问两个链表i和j并分别找到对应的边结点,这给针对图的边的操作(标记或删除)带来不便利。邻接多重表因此而演变过来的。
邻接多重表中,无向图中的每一个顶点分配一个顶点结点,所有顶点结点构成一个顶点数组adjmultiList[num]。另外每条边也分配一个边结点。
顶点结构如下所示:
其中data用来记录顶点的信息,firstEdge用来表示依附于该顶点的第一条边。
顶点数组如下所示:
边结点结构如下所示:
其中mark表示标志位,用于标记该边是否已经被访问过;iVex和jVex表示该边的两个顶点在顶点数组adjmultiList[num]中的位置;iLink和jLink分别表示指向依附于顶点iVex和jVex下一条边的指针。
从上面的顶点和边的结构来看,邻接多重表和邻接表的主要区别在于:邻接多重表中的边结点同时被链入对应边顶点的链表内(2条);邻接表中的边用两个表结点表示。另外,邻接多重表中的边结点就表示一条边,比较容易理解。
举个例子。某无向图如下图所示:
当采用邻接表表示该无向图时,其邻接表入下图所示:
如上图所示,图中黄色标记的结点表示A-D之间的边,在邻接表中一条边需要两个结点表示。因此如果对于边的操作(标记或者删除)则需要访问两条链表。
当采用邻接多重表表示该无向图时,其邻接多重表入下图所示:
如上图所示,结点A-D 之间的边,在邻接多重表中只需要一个边结点既可以表示。另外,在该结构中,每个边结点被链入了两个不同的链表。其中A-D之间的边被链入了红色和绿色标记的链表中。如果需要访问一条边,则可以从该边的两个顶点结点中的任何一个出发,遍历依附于该顶点的边构成的链表即可。如果需要删除一条边,则只需要删除一个边结点,但是需要修改这条边依附的两个顶点所对应的链表。另外,需要注意的是,在无向图中,边结点中的iVex和jVex链域与该边所依附的顶点无关,即iVex=0,jVex=3和iVex=3,jVex=0这都表示同一条边A-D,因此这给链表的指针修改带来一定的麻烦。
基本操作
1、建立无向图的邻接多重表
输入ABCDE五个顶点V={A,B,C,D,E},然后输入边E={(A,B),(B,C),(B,E),(C,D),(C,E),(D,A)},建立如下无向图: