数据结构
//数据结构
typedef struct Side//边
{
int toVertex;//边指向的点
struct side *next;
}Side,*sLink;
typedef struct Vertex//顶点
{
int data;
sLink first;//第一个边
}Vertex,AdjList[20];
typedef struct Graph//图
{
AdjList adj;//顶点数组,注意不是指针,用.不用->
int n,v;//顶点数,边数
}Graph,*gLink;
创建图
//创建
void createGraph(gLink g)
{
int n,v,data;
printf("请输入顶点数与边数");
scanf("%d %d",&n,&v);
g->n = n;
g->v = v;
int i;
for(i=0;i<n;i++)
{
printf("请输入顶点%d权值",i);
scanf("%d",&data);
g->adj[i].data = data;
g->adj[i].first = NULL;
}
printf("请输入边信息");
int v1,v2;
for(i=0;i<v;i++)
{
scanf("%d %d",&v1,&v2);
sLink s = (sLink)malloc(sizeof(Side));
s->toVertex = v2;
s->next = g->adj[v1].first;
g->adj[v1].first = s;
}
}
拓扑排序
求每个点的初始入度
遍历邻接表,由于每一条边指向一个顶点,所以找到一条边则为其指向的顶点入度加1。
a为存放入度的数组,下标与顶点下标对应
void inDegree(gLink g,int *a)
{
int i;
for(i=0;i<g->n;i++)
{
a[i]=0;
}
for(i=0;i<g->n;i++)
{
sLink s = g->adj[i].first;
while(s)
{
a[s->toVertex]++;
s = s->next;
}
}
}
拓扑排序
1、求初始入度
2、将最初入度为0的顶点入队
3、队列不为空则循环
3.1、出队一个顶点,输出值
3.2、将其所有边指向的顶点入度减1,若减完后有顶点入度变为0,则入队
3.3、回到3
//拓扑排序
void tuopu(gLink g)
{
Vertex queue[10];
int front=0, rear=0;
int a[g->n];
inDegree(g,a);
int i;
for(i=0;i<g->n;i++)
{
if(!a[i])
{
queue[rear++] = g->adj[i];
}
}
while(front!=rear)
{
Vertex v = queue[front++];
printf("%d,",v.data);
sLink s = v.first;
while(s)
{
if(!--a[s->toVertex])
{
queue[rear++] = g->adj[s->toVertex];
}
s = s->next;
}
}
}
主函数
int main()
{
gLink g = (gLink)malloc(sizeof(Graph));
createGraph(g);
tuopu(g);
return 0;
}