java图的拓扑排序,图的拓扑排序

拓扑排序

拓扑排序是对有向无圈图的顶点的一种排序,它使得如果存在一条从(v_i)到(v_j)的路径,那么在排序中(v_j)出现在(v_i)的后面。如果图含有圈,那么拓扑排序是不可能的。此外,排序不必是唯一的;任何合理的排序都是可以的。

算法思想

第1种

先找出任意一个没有入边的顶点。然后显示出该顶点,并将它和它的边一起从图中删除。然后对图的其余部分应用同样的方法处理。

伪代码

void Topsort(Graph G)

{

int Counter;

Vertex V, W;

for(Counter = 0; Counter < NumVertex; Counter++)

{

V = FindNewVertexOfIndegreeZero();

if(V == NotAVertex)

{

Error("Graph has a cycle");

break;

}

TopNum[V] = Counter; // 或打印出

for each W adjancent to V

Indegree[W]--;

}

}

函数FindNewVertexOfIndegreeZero扫描Indegree数组,寻找一个尚未被分配拓扑编号的入度为0的顶点;因为其是对Indegree数组的一个简单的顺序扫描,所以每次对它的调用都花费(O(left | Vight |))的时间.由于有(left | Vight |)这样的调用,因此该算法的运行时间为(O({left | Vight |}^2))。

第2种

首先,对每一个顶点计算它的入度(可以在输入图时就计算)。然后将所以入度为0的顶点放入一个初始为空的的队列中。当队列不空时,删除一个顶点(v),并将(v)邻接的所有的顶点的入度减1.只要1个顶点的入度将为0,就把该顶点放入队列中。此时,拓扑排序就是顶点出队的顺序。

C语言代码

void Topsort(ALGraph G)

{

Queue Q;

int Counter;

VertexType V;

ArcNode W;

Q = CreateQueue(MVNum);

Counter = 0;

for (V = 1; V <= G->vexnum; V++)

if (G->Indegree[V] == 0)

Enqueue(V, Q);

while (!IsEmpty(Q))

{

V = FrontAndDequeue(Q);

printf("%d->", V);

Counter++;

W = G->vertices[V].firstarc;

while (W != NULL)

{

if (--G->Indegree[W->adjvex] == 0)

Enqueue(W->adjvex, Q);

W = W->nextarc;

}

}

printf("^

");

if (Counter != G->vexnum)

printf("Graph has a cycle

");

DisposeQueue(Q);

}

如果使用邻接表,那么执行这个算法所用的时间为(O(left | Eight | +left | Vight | ))。

完整C语言代码

#include

#include

#define NotAVertex (-1)

#define MVNum (10) // 最大顶点数

typedef int VertexType;

typedef int ArcType;

typedef struct ArcNode // 边结点

{

VertexType adjvex; // 该边所指向的顶点的位置

struct ArcNode *nextarc; // 指向下一条边的指针

ArcType weight; // 边的权值

} * ArcNode;

typedef struct VNode // 顶点信息

{

// VertexType data;

ArcNode firstarc; // 指向第一条依附该顶点的边的指针

} VNode, AdjList[MVNum]; // AdjList 表示邻接类型

typedef struct // 邻接表

{

AdjList vertices;

int vexnum, arcnum; // 图的当前定点数和边数

int Indegree[MVNum]; // 每个顶点的入度

} * ALGraph;

void CreateUDG(ALGraph G)

{

int i, j;

int v1, v2;

ArcNode p1, p2;

ArcType weight;

printf("Input vexnum: ");

scanf("%d", &G->vexnum);

printf("Input arcnum: ");

scanf("%d", &G->arcnum);

// 输入各点,构造表头结点表

for (i = 1; i <= G->vexnum; i++)

{

G->vertices[i].firstarc = NULL;

G->Indegree[i] = 0;

}

// 输入一条边依附的两个顶点

for (j = 0; j < G->arcnum; j++)

{

scanf("%d%d%d", &v1, &v2, &weight);

p1 = (ArcNode)malloc(sizeof(*p1));

if (p1 == NULL)

exit(0);

p1->adjvex = v2;

p1->weight = weight;

p1->nextarc = G->vertices[v1].firstarc;

G->vertices[v1].firstarc = p1;

G->Indegree[v2] += 1;

/*p2 = (ArcNode)malloc(sizeof(struct ArcNode));

p2->adjvex = i;

p2->nextarc = G->vertices[j].firstarc;

G->vertices[j].firstarc = p2;

G->Indegree[v1] += 1;*/

}

}

ALGraph CreateGraph(void)

{

ALGraph G;

G = (ALGraph)malloc(sizeof(*G));

if (G == NULL)

exit(0);

return G;

}

typedef VertexType ElementType;

typedef struct QueueNode *Queue;

struct QueueNode

{

ElementType Array[MVNum];

int Capacity;

int Size;

int Front;

int Rear;

};

int IsFull(Queue Q)

{

return Q->Size == Q->Capacity;

}

int IsEmpty(Queue Q)

{

return Q->Size == 0;

}

Queue CreateQueue(int Capacity)

{

Queue Q;

Q = (Queue)malloc(sizeof(struct QueueNode));

if (Q == NULL)

exit(0);

Q->Capacity = Capacity;

Q->Size = 0;

Q->Front = 1;

Q->Rear = 0;

return Q;

}

void Enqueue(ElementType X, Queue Q)

{

if (IsFull(Q))

{

printf("The queue is full

");

system("pause");

exit(0);

}

Q->Size++;

if (++Q->Rear == Q->Capacity)

Q->Rear = 0;

Q->Array[Q->Rear] = X;

}

void Dequeue(Queue Q)

{

if (IsEmpty(Q))

{

printf("The queue is empty

");

system("pause");

exit(0);

}

Q->Size--;

if (++Q->Front == Q->Capacity)

Q->Front = 0;

}

ElementType Front(Queue Q)

{

if (IsEmpty(Q))

{

printf("The queue is empty

");

system("pause");

exit(0);

}

return Q->Array[Q->Front];

}

ElementType FrontAndDequeue(Queue Q)

{

if (IsEmpty(Q))

{

printf("The queue is empty

");

system("pause");

exit(0);

}

Q->Size--;

return Q->Array[(Q->Front++) % Q->Capacity];

}

void DisposeQueue(Queue Q)

{

free(Q);

}

void Topsort(ALGraph G)

{

Queue Q;

int Counter;

VertexType V;

ArcNode W;

Q = CreateQueue(MVNum);

Counter = 0;

for (V = 1; V <= G->vexnum; V++)

if (G->Indegree[V] == 0)

Enqueue(V, Q);

while (!IsEmpty(Q))

{

V = FrontAndDequeue(Q);

printf("%d->", V);

Counter++;

W = G->vertices[V].firstarc;

while (W != NULL)

{

if (--G->Indegree[W->adjvex] == 0)

Enqueue(W->adjvex, Q);

W = W->nextarc;

}

}

printf("^

");

if (Counter != G->vexnum)

printf("Graph has a cycle

");

DisposeQueue(Q);

}

int main()

{

ALGraph G;

G = CreateGraph();

CreateUDG(G);

Topsort(G);

system("pause");

return 0;

}

输入/输出

顶点按数字编号,第3个数子为边上的权值。

Input vexnum: 7

Input arcnum: 12

1 2 1

1 3 1

3 6 1

7 6 1

5 7 1

2 5 1

1 4 1

2 4 1

5 4 1

4 7 1

4 6 1

4 3 1

1->2->5->4->3->7->6->^

请按任意键继续. . .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值