有向图的十字链表表示法
代码实现:
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define MAXNum 100
//定义无穷大
#define MAXInt 32767
typedef int Status;
//定义顶点数据类型
typedef char VerTexType;
//定义节点权重的类型
typedef int OtherInfo;
//定义弧结点的类型
typedef struct ArcNode{
int startvex;
ArcNode* start;
int endvex;
ArcNode* end;
OtherInfo info;
}ArcNode;
//定义表结点的数据类型
typedef struct VNode {
VerTexType data;
ArcNode* firstin;//以data结点为尾的弧,即other→data
ArcNode* firstout;//以data结点为头的弧,即data→other
}VNode,AdjList[MAXNum];
//定义图的数据类型
typedef struct {
AdjList vertices;//十字链表
int vexnum, arcnum;//图的结点总个数以及总边数
}ALGraph;
//查找结点数据x在邻接表中处于什么位置
int Locate(ALGraph G, VerTexType x) {
for (int i = 0; i < G.vexnum; i++) {
if (G.vertices[i].data == x) {
return i;
}
}
return -1;
}
Status createTenList(ALGraph& G) {
cout << "请输入图的总结点数和总弧数:" << "\n";
cin >> G.vexnum >> G.arcnum;
cout << "请依次输入每个结点:" << "\n";
for (int i = 0; i < G.vexnum; i++) {
cin >> G.vertices[i].data;
G.vertices[i].firstin = NULL;
G.vertices[i].firstout = NULL;
}
cout << "请依次输入每条弧的起点以及终点:" << "\n";
for (int i = 0; i < G.arcnum; i++)
{
VerTexType x, y;
cin >> x >> y;
//查找结点x,y在顶点表中的下标
int xIndex=Locate(G, x);
int yIndex=Locate(G, y);
if (xIndex==-1||yIndex==-1)
{
return -1;
}
else {
//创建结点,startvex是xIndex,endvex是yIndex的结点
ArcNode* newNode = new ArcNode;
newNode->startvex = xIndex;
newNode->endvex = yIndex;
newNode->info = 1;
//将该结点添加到以xIndex为起始结点的链表上
newNode->start = G.vertices[xIndex].firstin;
G.vertices[xIndex].firstin = newNode;
//将该结点添加到以yIndex为尾结点的链表上
newNode->end = G.vertices[yIndex].firstout;
G.vertices[yIndex].firstout = newNode;
}
}
return OK;
}
void outPut(ALGraph G) {
cout << "输出顶点表如下\n" << "";
for (int i = 0; i < G.vexnum; i++)
{
cout << G.vertices[i].data << " ";
}
for (int i = 0; i < G.vexnum; i++)
{
ArcNode* pFirst=G.vertices[i].firstin;//获取i结点入度表的第一条边
ArcNode* pLast=G.vertices[i].firstout;//获取i结点入度表的第一条边
printf("\n以%c结点为起点的边为:\n",G.vertices[i].data);
while (pFirst)
{
printf(" 边:%c %c", G.vertices[pFirst->startvex].data, G.vertices[pFirst->endvex].data);
pFirst = pFirst->start;
}
printf("\n以%c结点为起终点的边为:\n", G.vertices[i].data);
while (pLast)
{
printf(" 边:%c %c", G.vertices[pLast->startvex].data, G.vertices[pLast->endvex].data);
pLast = pLast->end;
}
}
}
//求某个点的出度
int outDegree(ALGraph G, VerTexType x) {
int outDegree = 0;
for (int i = 0; i < G.vexnum; i++)
{
if (G.vertices[i].data==x)
{
ArcNode* p = G.vertices[i].firstin;
while (p)
{
outDegree++;
p = p->start;
}
break;
}
}
return outDegree;
}
//求某个点的入度
int InDegree(ALGraph G, VerTexType x) {
int inDegree = 0;
for (int i = 0; i < G.vexnum; i++)
{
if (G.vertices[i].data == x)
{
ArcNode* p = G.vertices[i].firstout;
while (p)
{
inDegree++;
p = p->end;
}
break;
}
}
return inDegree;
}
int main() {
ALGraph G;
createTenList(G);
outPut(G);
VerTexType x;
cout << "\n请输入需要求出度和入度的结点:" << "\n";
cin >> x;
int out = outDegree(G, x);
printf("\n该结点的出度为:%d\n", out);
int in = InDegree(G, x);
printf("\n该结点的入度为:%d\n", in);
return 0;
}
测试样例:
输入的测试样例为上述的有向图: