#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#define Default_Vertex_Size 10
#define T char
typedef struct Edge
{
int dest;
struct Edge *link;
}Edge;
typedef struct Vertex
{
T data;
Edge *adj;
}Vertex;
typedef struct GraphLnk
{
int MaxVertices; //最大点数量
int NumVertices;
int NumEdges;
Vertex *NodeTable;
}GraphLnk;
void InitGraph(GraphLnk *g);
void ShowGraph(GraphLnk *g);
void InsertVertex(GraphLnk *g,T v);
void InsertEdge(GraphLnk *g,T v,T w);
void RemoveEgde(GraphLnk *g,T vertex1,T vertex2);
void RemoveVertex(GraphLnk *g,T vertex);
void DestroyGraph(GraphLnk *g);
int GetFirstNeighbor(GraphLnk *g,T vertex);
int GetNextNerghbor(GraphLnk *g,T vertex1,T vertex2);
//拓扑排序
void TopologiclSort(GraphLnk *g);
void TopologiclSort(GraphLnk *g)
{
int n = g->NumVertices;
int *count = (int*)malloc(sizeof(int)*n);
assert(count!=nullptr);
for(int i=0;i<n;i++)
count[i] = 0;
Edge *p;
for(int i=0;i<n;i++)
{
p = g->NodeTable[i].adj;
while(p!=NULL)
{
count[p->dest]++;
p = p->link;
}
}
/*for(int i=0;i<n;i++)
{
printf("%d\n",count[i]);
}*/
int top = -1;
for(int i=0;i<n;++i)
{
if(count[i]==0)
{
count[i] = top;
top = i;
}
}
int v,w;
for(int i=0;i<n;++i)
{
if(top==-1)
printf("有回路!\n");
else
{
v = top;
top = count[top];
printf("%c-->",g->NodeTable[v]);
w = GetFirstNeighbor(g,g->NodeTable[v].data);
while(w!=-1)
{
if(--count[w]==0)
{
count[w] = top;
top = w;
}
w = GetNextNerghbor(g,g->NodeTable[v].data,g->NodeTable[w].data);
}
}
}
}
//初始化
void InitGraph(GraphLnk *g)
{
g->MaxVertices = Default_Vertex_Size;
g->NumEdges = g->NumVertices = 0;
g->NodeTable = (Vertex*)malloc(sizeof(Vertex)*g->MaxVertices);
assert(g->NodeTable!=NULL);
for(int i=0;i<g->MaxVertices;++i)
{
g->NodeTable[i].adj = NULL;
}
}
//输出图结构
void ShowGraph(GraphLnk *g)
{
Edge *p;
for(int i=0;i<g->NumVertices;i++)
{
p = g->NodeTable[i].adj;
printf("%d %c:>",i,g->NodeTable[i].data);
while(p != NULL)
{
printf("%d-->",p->dest);
p = p->link;
}
printf("Nul. \n");
}
}
//插入点结构
void InsertVertex(GraphLnk *g,T v)
{
if(g->NumVertices>=g->MaxVertices)
return;
g->NodeTable[g->NumVertices++].data = v;
}
int GetVertexPos(GraphLnk *g,T v)
{
for(int i=0;i<g->NumVertices;++i)
if(g->NodeTable[i].data == v)
return i;
return -1;
}
//插入两点之间的边
void InsertEdge(GraphLnk *g,T v,T w)
{
int v1 = GetVertexPos(g,v);
int v2 = GetVertexPos(g,w);
if(v1 == -1 || v2 == -1)
return;
Edge *s;
//V1 -- V2
s = (Edge*)malloc(sizeof(Edge));
assert(s!=NULL);
s->dest = v2;
s->link = g->NodeTable[v1].adj; //头插法 进行边节点的插入
g->NodeTable[v1].adj = s;
//V2 -- V1
//s = (Edge*)malloc(sizeof(Edge));
//assert(s!=NULL);
//s->dest = v1;
//s->link = g->NodeTable[v2].adj;
//g->NodeTable[v2].adj = s;
g->NumEdges++;
}
//删除两点之间的边
void RemoveEgde(GraphLnk *g,T vertex1,T vertex2)
{
int v1 = GetVertexPos(g,vertex1);
int v2 = GetVertexPos(g,vertex2);
if(v1 == -1 || v2 == -1)
{
return;
}
Edge *q;
Edge *p;
//因为是无向图
//删除v1 -- v2边
p = g->NodeTable[v1].adj;
while(p != NULL && p->dest!=v2)
{
q = p;
p = p->link;
}
if(p == NULL)
{
return;
}
if(q == NULL)
{
g->NodeTable[v1].adj = p->link;
}
else{
q->link = p->link;
}
free(p);
//删除v2 -- v1边
p = g->NodeTable[v2].adj;
while(p->dest != v1)
{
q = p;
p = p->link;
}
if(q == NULL)
{
g->NodeTable[v2].adj = p->link;
}
else
{
q->link = p->link;
}
free(p);
g->NumEdges--;
}
//删除图中的点以及删除与该点相连的边
void RemoveVertex(GraphLnk *g,T vertex)
{
int v = GetVertexPos(g,vertex);
if(v == -1)
{
return;
}
Edge *p = g->NodeTable[v].adj;
Edge *s;
Edge *t = NULL; //s的前驱
int k;
while(p!=NULL)
{
k = p->dest;
s = g->NodeTable[k].adj;
while(s!=NULL&&s->dest!=v) //寻找与删除点相关的边的下标
{
t = s;
s = s->link;
}
if(s!=NULL)
{
if(t==NULL)
{
g->NodeTable[k].adj = s->link;
}
else
{
t->link = s->link;
}
free(s);
}
g->NodeTable[v].adj = p->link;
free(p);
p = g->NodeTable[v].adj;
}
g->NumVertices--;
g->NodeTable[v].data = g->NodeTable[g->NumVertices].data;
g->NodeTable[v].adj = g->NodeTable[g->NumVertices].adj;
s = g->NodeTable[v].adj;
while(s != NULL)
{
k = s->dest;
p = g->NodeTable[k].adj;
while(p!=NULL)
{
if(p->dest == g->NumVertices)
{
p->dest = v;
break;
}
p = p->link;
}
s = s->link;
}
}
//摧毁图结构
void DestroyGraph(GraphLnk *g)
{
Edge *p;
for(int i=0;i<g->NumVertices;++i)
{
p = g->NodeTable[i].adj;
while(p != NULL)
{
g->NodeTable[i].adj = p->link;
free(p);
p = g->NodeTable[i].adj;
}
}
free(g->NodeTable);
g->NodeTable = NULL;
g->NumVertices = g->NumEdges = g->MaxVertices = 0;
}
//获取第一个邻接顶点
int GetFirstNeighbor(GraphLnk *g,T vertex)
{
int v = GetVertexPos(g,vertex);
if(v==-1)
return -1;
Edge *p = g->NodeTable[v].adj;
if(p != NULL)
return p->dest;
return -1;
}
//获取某点的下一个邻接点
int GetNextNerghbor(GraphLnk *g,T vertex1,T vertex2)
{
int v1 = GetVertexPos(g,vertex1);
int v2 = GetVertexPos(g,vertex2);
if(v1 ==-1 || v2 == -1)
{
return -1;
}
Edge *p = g->NodeTable[v1].adj;
while(p != NULL&& p->dest != v2)
{
p = p->link;
}
if(p!=NULL && p->link !=NULL)
return p->link->dest;
return -1;
}
int main()
{
GraphLnk gl;
//初始化
InitGraph(&gl);
//插入节点
InsertVertex(&gl,'A');
InsertVertex(&gl,'B');
InsertVertex(&gl,'C');
InsertVertex(&gl,'D');
InsertVertex(&gl,'E');
InsertVertex(&gl,'F');
InsertEdge(&gl,'A','B');
InsertEdge(&gl,'A','C');
InsertEdge(&gl,'A','D');
InsertEdge(&gl,'C','B');
InsertEdge(&gl,'C','E');
InsertEdge(&gl,'D','E');
InsertEdge(&gl,'F','D');
InsertEdge(&gl,'F','E');
ShowGraph(&gl);
TopologiclSort(&gl);
printf("Nul.\n");
ShowGraph(&gl);
DestroyGraph(&gl);
return 0;
}