最近做了一些数据结构有关图的习题,就在这里说一下自己做的题 以及走的弯路吧。
其中有几道比较经典的比如在一个有向图邻接表的存储结构上,算出这个图的入度和出度。下面是输入输出:
输入:
6 6
A B C D E F
A B
A C
B D
C D
D E
C F
输出:
A 0 2 2
B 1 1 2
C 1 2 3
D 2 1 3
E 1 0 1
F 1 0 1
其实写过的同学应该觉得很简单,但是也有很多人一头雾水,会觉得什么是邻接表,出入度又怎么实现。
其实邻接表很简单,就是将一个数组里存入图中有的顶点,然后每个数组元素又是一个链表,链着以它为起点,以其他点为终点的那个终点顶点。而在创建有向图和无向图时要注意,有向图有起点终点,而无向图没有,所以创建时两个端点都要连接。下面是邻接表的结构图:
知道了邻接表就可以开始干活了,至于连出度入度是什么都不知道的童鞋,可以百度一下,在此就不多赘述了。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define MAX_VERTEX_NUM 20
typedef struct ArcNode
{
int adjvex;
ArcNode *nextarc;
} ArcNode;
typedef struct Vnode
{
char data;
int in;
int out;
ArcNode * firstarc;
} Vnode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
int vexnum, arcnum;
} ALGraph;
先建一个连接表,然后将创建和输出的函数实现。
void CreatALGraph(ALGraph *G)
{
int i,j,k,weight;
char q,p;
ArcNode *s;
cin>>G->vexnum>>G->arcnum;
for(i=0; i<G->vexnum; i++)
{
cin>>G->vertices[i].data;
G->vertices[i].in = 0;
G->vertices[i].out = 0;
G->vertices[i].firstarc=NULL;
}
for(k=0; k<G->arcnum; k++)
{
cin>>q>>p;
i = q-'A';
j = p-'A';
G->vertices[j].in++;
G->vertices[i].out++;
s=(ArcNode*)malloc(sizeof(ArcNode));
s->adjvex=j;
s->nextarc=G->vertices[i].firstarc;
G->vertices[i].firstarc=s;
}
}
void outALGraph(ALGraph *G)
{
int i,sum=0;
for(i = 0; i<G->vexnum; i++)
{
sum = G->vertices[i].in+G->vertices[i].out;
cout<< G->vertices[i].data<<" "<<G->vertices[i].in<<" "<<G->vertices[i].out<<" "<<sum<<endl;
sum = 0;
}
}
最后是main函数
int main()
{
ALGraph *G = (ALGraph*)malloc(sizeof(ALGraph));
CreatALGraph(G);
outALGraph(G);
return 0;
}
由于题目的输入是A、B、C这样的顶点,我在创建时就把入度和出度就算了出来,这里注意结构体内部元素也要改变。
cin>>q>>p;
i = q-'A';
j = p-'A';
G->vertices[j].in++;
G->vertices[i].out++;
上面就是核心的算法,用ASCII码的加减法就实现了。