对于有向图来说,邻接表是有缺陷的。关心了出度问题,想了解入度就必须要遍历整个图才能知道,反之,逆邻接表解决了入度却不了解出度的情况。有没有可能把邻接表与逆邻接表结合起来呢?答案是肯定的,就是把它们整合在一起。这就是我们现在要讲的有向图的一种存储方法:十字链表(Orthogonal List)。
如果想要更容易的理解十字链表法的代码,最好在这之前将邻接表和逆邻接表的代码都能自行实现。在好一点就是能将图的十字链表存储结构示意图画出来。
十字链表图示:
#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef int edgetype; //权值类型,建立网图时需引进
#define MAXVEX 20
typedef struct ENode
{
int tailvex,headvex; //弧起点在顶点表的下标,弧终点在顶点表的下标
struct ENode *taillink,*headlink; //指向起点相同的下条边,指向终点相同的下条边
}EdgeNode;//边表结构
typedef struct VNode
{
datatype data;
EdgeNode *firstin,*firstout;//入边表头指针 ,出边表头指针
}VertexNode,OrtList[MAXVEX];//顶点结构
typedef struct
{
OrtList OrtList; //储存所有的顶点的数组
int numVertexes,numEdges;//图中顶点数,边或弧的个数
}GraphOrtList;//图结构--邻接表
void Creat_GraphOrtList(GraphOrtList *G);
void Print_GraphOrtList(GraphOrtList G);
int main()
{
GraphOrtList G;
Creat_GraphOrtList(&G);
Print_GraphOrtList(G);
}
//使用图的十字链表存储方式创建图 针对有向图的优化
void Creat_GraphOrtList(GraphOrtList *G)
{
int v_num,e_num;
int i,x,y;
EdgeNode *e;
datatype ch;
printf("Please input numVertexes,numEdges:");
scanf("%d,%d",&v_num,&e_num); //顶点个数 , 边或弧的个数
G->numVertexes=v_num;
G->numEdges=e_num;
//给每个顶点赋值
for(i=0;i<v_num;i++)
{
printf("Please input adjList[%d].data:",i);
scanf(" %c",&ch);
G->OrtList[i].data=ch;
G->OrtList[i].firstin=NULL;
G->OrtList[i].firstout=NULL; //入边表头指针,出边表头指针赋值NULL
}
//建立边表
for(i=0;i<e_num;i++)
{
printf("Please input <vi,vj>的下标:\n");
scanf(" %d,%d",&x,&y);
e=(EdgeNode*)malloc(sizeof(EdgeNode));
e->tailvex=x;
e->headvex=y;
//firstin:入边表头指针 firstout:出边表头指针
e->taillink=G->OrtList[x].firstout;//taillink:指向起点相同的下条边
G->OrtList[x].firstout=e;
e->headlink=G->OrtList[y].firstin;//headlink:指向终点相同的下条边
G->OrtList[y].firstin=e;
}
//n:顶点数,e:边数 时间复杂度--------->O(n+e)
}
//打印十字链表
void Print_GraphOrtList(GraphOrtList G)
{
int i;
EdgeNode *p;
printf("邻接表为:\n");
for(i=0;i<G.numVertexes;i++){
p=G.OrtList[i].firstout;
while(p){
printf("(%c,%c)",G.OrtList[i].data,G.OrtList[p->headvex].data);
p=p->taillink;
}
printf("\n");
}
printf("逆邻接表为:\n");
for(i=0;i<G.numVertexes;i++){
p=G.OrtList[i].firstin;
while(p){
printf("(%c,%c)",G.OrtList[p->tailvex].data,G.OrtList[i].data);
p=p->headlink;
}
printf("\n");
}
}
输出结果: