腰酸背痛一个上午,终于搞定了。。
一 用到二个工具:
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 }