拓扑排序

来源:互联网 发布:痤疮用云南白药知乎 编辑:程序博客网 时间:2024/05/05 11:31

对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。

拓扑排序(Topological Sort)

什么是拓扑序列

  通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。离散数学中关于偏序和全序的定义:
  若集合X上的关系是R是自反的、反对称的和传递的,则称R是集合X上的偏序关系。
  设R是集合X上的偏序(Partial Order),如果对每个x,y属于X必有xRy 或 yRx,则称R是集合X上的全序关系。
  注意:
  ①若将图中顶点按拓扑次序排成一行,则图中所有的有向边均是从左指向右的。
  ②若图中存在有向环,则不可能使顶点满足拓扑次序。
  ③一个DAG的拓扑序列通常表示某种方案切实可行。

举例

  【例】对如上学生选课工程图进行拓扑排序, 得到的拓扑有序序列为
  C1 , C2 , C3 , C4 , C5 , C6 , C8 , C9 , C7
  或 C1 , C8 , C9 , C2 , C5 , C3 , C4 , C7 , C6
  【例】一本书的作者将书本中的各章节学习作为顶点,各章节的先学后修关系作为边,构成一个有向图。按有向图的拓扑次序安排章节,才能保证读者在学习某章节时,其预备知识已在前面的章节里介绍过。
  ④一个DAG可能有多个拓扑序列。

实现的基本方法

  拓扑排序方法如下:
  (1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
  (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
  (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.

拓扑序列 C++核心代码

  bool TopologicalSort(int a[][101]) //可以完成拓扑排序则返回True
  {
  int n = a[0][0], i, j;
  int into[101], ans[101];
  memset(into, 0, sizeof(into));
  memset(ans, 0, sizeof(ans));
  for (i = 1; i <= n; i++)
  {
  for (j = 1; j <= n; j++)
  {
  if (a[i][j] > 0)
  into[j]++;
  }
  }
  into[0] = 1;
  for (i = 1; i <= n; i++)
  {
  j = 0;
  while (into[j] != 0)
  {
  j++;
  if (j > n)
  return false;
  }
  ans[i] = j;
  into[j] = -1;
  for (int k = 1; k <= n; k++)
  {
  if (a[j][k] > 0)
  into[k]--;
  }
  }
  for (i = 1; i <= n; i++)
  {
  cout << ans[i] << " ";
  }
  cout << endl;
  return true;
  }

原创粉丝点击