Министерство образования и науки Российской Федерации ГОУ ВПО Тамбовский государственный технический университет
Кафедра «Информационные системы и защита информации»
О Т Ч Е Т
о лабораторной работе № 3 на тему
«Топологическая сортировка»
Выполнил: студент гр. СИБ-21 Улитин А.Ю.
Проверил: доцент Кулаков Ю.В.
« » 2010 г.
(Подпись)
Тамбов 2010
Цель работы: Продемонстрировать работу алгоритма топологической сортировки элементов 1, 2, 3, ..., 9 для заданных отношений между ними.
Вариант № 15
Задание: Выполнить по алгоритму Т топологическую сортировку элементов 1, 2, 3, ..., 9 для заданных отношений между ними: 5<1, 5<8, 2<7, 4<2, 6<4, 4<7, 1<3, 8<1, 2<5, 9<8.
Теоретическая часть
Алгоритм Т (Топологическая сортировка). В этом алгоритме в качестве входного потока используется последовательность отношений j < к, обозначающих, что объект j предшествует объекту к в некотором частичном упорядочении при условии, что 1 < j, к < п. Выходной поток состоит из множества п объектов, расположенных в линейном порядке. При этом используются следующие внутренние таблицы: QLINK[0], COUNT[1] = QLINK[l], COUNT[2] = QLINK[2], ..., COUNT[n] = QLINKW; TOP[1], TOP[2], ..., T0P[n]; пул с одним узлом для каждого отношения входного потока и с указанными выше полями SUC и NEXT; переменная связи Р, которая используется для ссылки на узлы в пуле; целочисленные переменные F и R, применяемые для ссылок на начало и конец очереди, связи которых находятся в таблице QLINK; и, наконец, переменная N, позволяющая подсчитать количество объектов, которые необходимо поместить в выходной поток.
Т1. [Инициализация.] Ввести значение п. Установить COUNT[к]0 и ТОР [к] Λ для 1 < к < п. Установить Nп.
Т2. [Следующее отношение.] Получить отношение j<к из входного потока. Если входной поток исчерпан, перейти к шагу Т4.
ТЗ. [Запись отношения.] Увеличить на единицу значение COUNT [к]. Установить РAVAIL, SUC(P)к, NEXT(P) TOP[j], TOP[j] P.
(Это операция (8).) Вернуться к шагу Т2.
Т4. [Поиск нулей.] (В этом месте завершается ввод, и входной поток теперь имеет понятный для компьютера вид. Следующий шаг заключается в инициализации очереди выходного потока, который связан с помощью поля QLINK.) Установить R0и QLINK[0]0. Для 1 < к < п проверить значение COUNT [k] и, если оно равно нулю, установить QLINK[R]к и Rк. После выполнения этого действия для всех к установить FQLINK[0] (теперь оно будет содержать первое значение к, для которого COUNT[k] равно нулю).
Т5. [Вывод начала очереди.] Вывести значение F. Если F = 0, перейти к шагу Т8, в противном случае установить NN-1 и установить РTOP[F]. (Так как таблицы QLINK и COUNT перекрываются, получим QLINK [R] = 0. Следовательно, условие F = 0 выполняется, когда очередь пуста.)
Т6. [Удаление отношений.] Если Р = Λ, перейти к шагу Т7. В противном случае уменьшить на единицу значение COUNT[SUC(P)], а если оно уже равно нулю, установить QLINK[R]SUC(P) и RSUC(P). Установить Р NEXT(P) и повторить этот шаг. (Таким образом удаляем из системы все отношения вида F < к для некоторого к и располагаем новые узлы в очереди, когда все их предшественники уже выведены.)
Т7. [Удаление из очереди.] Установить FQLINK[F] и вернуться к шагу Т5.
Т8. [Конец процесса.] Прекращение работы алгоритма. Если N = 0, получим в результате искомое "топологическое упорядочение" пронумерованных объектов, за которыми следует нуль. В противном случае N пронумерованных объектов не будут выведены из-за того, что они образуют замкнутую петлю, а это нарушает гипотезу о частичном упорядочении.
Практическая часть
Текст программы на языке Си
#include <stdlib.h>
#include <stdio.h>
struct sP {
int suc;
sP* next;
};
int count[10];
sP* top[10];
sP* P;
int N;
int R;
int F;
void T3(int j, int k) {
count[k]++;
P = (sP*) malloc(sizeof (sP));
P->suc = k;
P->next = top[j];
top[j] = P;
}
int main(int argc, char** argv) {
//T1 - начальная установка
for (int k = 1; k <= 9; k++) {
count[k] = 0;
top[k] = NULL;
}
N = 9;
//T2 и T3 - ввод и регистрация отношений
T3(5, 1);
T3(5, 8);
T3(2, 7);
T3(4, 2);
T3(6, 4);
T3(4, 7);
T3(1, 3);
T3(8, 1);
T3(2, 5);
T3(9, 8);
//T4 - поиск нулей
R = 0;
count[0] = 0;
for (int k = 1; k <= N; k++) {
if (count[k] == 0) {
count[R] = k;
R = k;
}
}
F = count[0];
while (F != 0) {
//T5 - Вывод из начала очереди
printf("%i,", F);
N--;
P = top[F];
//T6 - Стирание отношений
while (P != NULL) {
count[P->suc]--;
if (count[P->suc] == 0) {
count[R] = P->suc;
R = P->suc;
}
P = P->next;
}
// T7 - исключение из очереди
F = count[F];
}
//T8 окончание процесса
if(N==0) { // все элементы выведены
} else { // остались элементы которые находятся в цикле
printf("\nOther elements in the cycle\n");
}
return 0;
}
Результаты работы программы
6 9 4 2 5 7 8 1 3
Заключение
В ходе выполнения лабораторной работы я понял, как происходит топологическая сортировка элементов 1, 2, 3, ..., 9 для заданных отношений между ними.