求有向无环图的所有拓扑序列

腰酸背痛一个上午,终于搞定了。。

一 用到二个工具:

    1.回溯法的算法思想

    2.顺序表(主要用到了删除操作)

二 程序设计步骤:

    1.读入图;

       这里我没有用严格的图结构。而是用邻接矩阵来表示图,邻接矩阵放在一个txt文件中。(见后文)

       读入图就是指读入这个文件。

    2.计算图中顶点的入度;

       用一个结构体数组来存放顶点名称和顶点的入度(我这里的结构体名称是ElemType)

    3.初始化顺序表

       这一步只需初始化第0号顺序表。。。

       用2中的顶点入度数组来初试化。

    4.开始计算拓扑序列

       这里我们把图的每个顶点比作一个球,每个顺序表比作一个袋子。

       假设图有十个顶点,则需要十个袋子。(100个顶点,需要100个袋子。。。)

       这个问题与常见回溯算法不同的一个特点:从前一个袋子里取出球后,才能知道下一个袋子里装的是那几个球。

       思想如下:

       (1)将所有的球装入第0号袋子;

       (2)从袋子中取出一个球。如果合法(即入度为0),进行下一步;如果非法(即入度不为0),取下一个球。

       (3)根据(2)中取出的球,计算下一个袋子中的球的情况。上一步袋子中的球,除去取出的球外,全部放入下一个袋子(假设为A号袋子)中。根据取出的球(即顶点),

          计算A号袋子中球(即顶点)的入度。

       (4)重复步骤(2),每次袋子中都会少一颗球,直到最后一个袋子。取球的顺序即该图的一个拓扑排序;

       (5)从最后一个袋子开始回溯,直到回到第0号袋子,并把第0号袋子中的球取完为止。

    5.输出

三 示例

    1.需要拓扑排序的图

求有向无环图的所有拓扑序列

    2.存放邻接矩阵的文件。。

  

求有向无环图的所有拓扑序列

    3.代码

     (1)我的一个存放顺序表操作的头文件。。 

1 #pragma once 2 #ifdef ElemType 3 #else 4 #define ElemType int 5 #endif 6 #ifdef MaxSize 7 #else 8 #define MaxSize 10 9 #endif 10 11 //顺序表 12 struct sqList 13 { 14 ElemType data[MaxSize]; 15 int length; 16 }; 17 typedef struct sqList SqList; 18 19 //初始化 20 void init(SqList* list) 21 { 22 list->length = 0; 23 return; 24 } 25 26 //求长度 27 int getLength(SqList* list) 28 { 29 return list->length; 30 } 31 32 //插入 33 int insert(SqList* list, int n, ElemType x) 34 { 35 if (list->length >= MaxSize || n < 0 || n > list->length) 36 { 37 return 0; 38 } 39 int i = list->length; 40 while (i > n) 41 { 42 list->data[i] = list->data[i - 1]; 43 i--; 44 } 45 list->data[n] = x; 46 list->length++; 47 return 1; 48 } 49 50 //删除 51 int del(SqList* list, int n, ElemType* x) 52 { 53 if (n < 0 || n > list->length - 1) 54 { 55 return 0; 56 } 57 int i = n; 58 *x = list->data[i]; 59 while (i < list->length - 1) 60 { 61 list->data[i] = list->data[i + 1]; 62 i++; 63 } 64 list->length--; 65 return 1; 66 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfffg.html