有向图也可以用十字链表表示:应为有向图由于不对称性,导致其矩阵表示里面会出现很多0,例如下面的有向图的矩阵表示:
V1 | V2 | V3 | V4 | |
V1 | 0 | A | B | 0 |
V2 | 0 | 0 | 0 | 0 |
V3 | C | 0 | 0 | D |
V4 | E | F | G | 0 |
由于对于有向图的矩阵肯定是方阵,所以可以将行列链表的头节点合并;具体数据结构代码如下:
const
int
MAX_VERTEX_NUM
=
20
;
typedef struct ArcBox
... {
int tailvex, headvex;
ArcBox *hlink, *tlink;
int info; //弧的相关信息,权值.
} ArcBox;
typedef struct VexNode
... {
int data;
ArcBox *firstIn, *firstOut; //指向该顶点的第一个入弧,出弧
} VexNode;
typedef struct
... {
VexNode xList[MAX_VERTEX_NUM];
int vexNum, arcNum;
} OLGraph; // 十字链表:Orthogonal List;
int LocateVex(OLGraph & G, int & e)
... {
for (int i=0; i<G.vexNum; i++)
if(G.xList[i].data==e)
return i;
}
bool CreatDG(OLGraph & G)
... {
//采用十字链表存储表示,构造有向图.
cin>>G.vexNum>>G.arcNum; //顶点数,弧数;
for(int i=0; i<G.vexNum; i++)
...{
cin>>G.xList[i].data;
G.xList[i].firstIn=G.xList[i].firstOut=NULL;
}
for (int k=0; k<G.arcNum; k++)
...{
int v1, v2, value; //弧的起点,终点, 权值
cin>>v1>>v2>>value;
int i=LocateVex(G, v1); int j=LocateVex(G, v2);
ArcBox* ptem=new ArcBox;
ptem->tailvex=i; ptem->headvex=j; ptem->info=value;
ptem->hlink=G.xList[j].firstIn; ptem->tlink=G.xList[i].firstOut;
G.xList[j].firstIn=G.xList[i].firstOut=ptem;
}
return true;
}
// 输出各行元素
void DisplayRow(OLGraph & dest)
... {
for (int i=0; i<dest.vexNum; i++)
...{
ArcBox *tem;
tem=dest.xList[i].firstIn;
while (tem)
...{
cout<<"( "<<tem->tailvex<<", ";
cout<<tem->headvex<<", ";
cout<<tem->info<<" )";
tem=tem->hlink;
}
cout<<endl;
}
}
typedef struct ArcBox
... {
int tailvex, headvex;
ArcBox *hlink, *tlink;
int info; //弧的相关信息,权值.
} ArcBox;
typedef struct VexNode
... {
int data;
ArcBox *firstIn, *firstOut; //指向该顶点的第一个入弧,出弧
} VexNode;
typedef struct
... {
VexNode xList[MAX_VERTEX_NUM];
int vexNum, arcNum;
} OLGraph; // 十字链表:Orthogonal List;
int LocateVex(OLGraph & G, int & e)
... {
for (int i=0; i<G.vexNum; i++)
if(G.xList[i].data==e)
return i;
}
bool CreatDG(OLGraph & G)
... {
//采用十字链表存储表示,构造有向图.
cin>>G.vexNum>>G.arcNum; //顶点数,弧数;
for(int i=0; i<G.vexNum; i++)
...{
cin>>G.xList[i].data;
G.xList[i].firstIn=G.xList[i].firstOut=NULL;
}
for (int k=0; k<G.arcNum; k++)
...{
int v1, v2, value; //弧的起点,终点, 权值
cin>>v1>>v2>>value;
int i=LocateVex(G, v1); int j=LocateVex(G, v2);
ArcBox* ptem=new ArcBox;
ptem->tailvex=i; ptem->headvex=j; ptem->info=value;
ptem->hlink=G.xList[j].firstIn; ptem->tlink=G.xList[i].firstOut;
G.xList[j].firstIn=G.xList[i].firstOut=ptem;
}
return true;
}
// 输出各行元素
void DisplayRow(OLGraph & dest)
... {
for (int i=0; i<dest.vexNum; i++)
...{
ArcBox *tem;
tem=dest.xList[i].firstIn;
while (tem)
...{
cout<<"( "<<tem->tailvex<<", ";
cout<<tem->headvex<<", ";
cout<<tem->info<<" )";
tem=tem->hlink;
}
cout<<endl;
}
}
/*测试输入:
4 7 //顶点数,行数
1 2 3 4 //顶点数据
1 2 10 //弧的信息:尾,头,权值
1 3 11
3 1 12
3 4 13
4 1 14
4 2 15
4 3 16*/
/*测试输出:
( 3, 0, 14 )( 2, 0, 12 )
( 3, 1, 15 )( 0, 1, 10 )
( 3, 2, 16 )( 0, 2, 11 )
( 2, 3, 13 )
*/