Лабораторная работа №2
.DOC
Лабораторная работа N 2
Тема: |
Алгоритм прохода графа в глубину и в ширину.
|
Цель работы: |
Изучение алгоритмов поиска в графе, а также различных форм организации хранения и обработки данных. Разработка программы, реализующей алгоритм поиска в глубину. Изучение алгоритмов поиска в графе. Разработка программы, выполняющей поиск в ширину.
|
Структуры данных:
тип списков -
|
Каждый тип списков определяет множество конечных последовательностей элементов, имеющий заданный базисный тип. Число элементов списка, называемое его длиной, в разных списках одного типа может быть различным. Список, не имеющий элементов, называется пустым. Для списка определены понятия начального, конечного и текущего элементов, а также следующего и предыдущего элементов по отношению к текущему. Текущий элемент- это тот единственный элемент списка, который в данный доступен для обработки.
|
Тип очередей -
|
Очередь используется для реализации такой дисциплины обработки элементов списка, при которой элементы списка удаляются из него в порядке их включения в список (т.е. по принципу "Первым пришел - первым ушел").
Набор базисных операций над списками, являющимися очередями, состоит из четырех операций: 1)Создание пустой очереди; 2)Проверка очереди на пустоту; 3)Выборки первого элемента из очереди с одновременным его удалением; 4) Занесения некоторого значения базисного типа в качестве нового последнего элемента очереди.
|
Тип стеков -
|
Стек используется для реализации такой дисциплины обработки элементов списка, при которой элементы списка удаляются из него в порядке, обратном порядку их занесения в стек (т.е. по принципу "Последним пришел – первым ушел"). Набор базисных операций над списками, являющимися стеками, состоит из пяти операций: 1) Создание пустого стека; 2) Проверка стека на пустоту; 3,4) Выборки последнего элемента из стека без удаления его из стека или с его удалением; 5) Занесения некоторого значения базисного типа в качестве нового последнего элемента стека.
|
Тип деревьев -
|
Над некоторым базисным типом определяют множество структур, каждая из которых состоит из объекта базисного типа, называемого вершиной или корнем данного дерева, и некоторого списка элементов из определяемого множества, называемых поддеревьями данного дерева. Дерево, в котором список поддеревьев пуст, называется тривиальным, а корень тривиального дерева - листом дерева. Корень дерева называется отцом вершин, являющихся корнями поддревьев; а эти вершины называются сыновьями корня дерева, причем корень первого поддерева является старшим сыном, а корень каждого следующего поддерева в списке называется братом корня предыдущего поддерева. Набор базисных операций для деревьев состоит из следующих операций: Создание тривиального дерева по элементу базисного типа и выборки или замены корня дерева или списка его поддеревьев, а также всех операций (для списка поддеревьев), которые являются базисными для списка.
|
Обход графа в глубину -
|
При обходе дерева в глубину (известном также как прохождение в прямом порядке) вершины дерева посещаются в соответствии со следующей рекурсивной процедурой: сначала посетить корень дерева q; затем если корень рассматриваемого дерева не является листом, то для каждого сына p корня q рекурсивно обратиться к процедуре обхода в глубину для того, чтобы обойти все поддеревья с корнями p в порядке упорядоченности вершин p как сыновей корня q.
|
Алгоритм поиска в ширину -
|
Обход графа в ширину, как и обход в глубину должен обеспечивать днократное посещение каждой вершины графа, только по другому принципу. После посещения исходной вершины, из которой начинается поиск, посещаются все вершины, смежные с данной, затем, все вершины, смежные с этими вершинами и т.д., пока не будут посещены все вершины графа. Очевидно, что для этого необходимо, чтобы заданный граф был связанным. Способ обхода дерева в ширину, называемый иногда способом прохождения в горизонтальном порядке, осуществляет посещение вершин дерева слева направо, уровень за уровнем вниз от корня.
|
Текст программы на языке C.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct gr //сруктура для списка смежности
{int num;
int ind;
struct gr *next;
};
typedef struct gr graf; //преобразование типа для удобства
graf *start,*current,**mas;
void inputss(void);
void shiri(int);
void nulind(void);
void glub(int);
int a,n=0,*masg;
void main()
{
int i,d;
clrscr();
inputss();
printf("\nvvedite koreni ");
scanf(" %d",&d);
shiri(d);
nulind();
masg=(int*)malloc(a*sizeof(int));
n=0;
masg[n]=d;
mas[d-1]->ind=1;
n=1;
glub(d);
printf("\nobhod v glubinu\n");
for(i=0;i<a;i++)
printf(" %d",masg[i]);
getch();
}
void inputss(void) //процедура ввода списка смежности
{
int i,d;
d=0;
printf ("Vvedite razmernosti massiva\nko-lvo versin ");
scanf (" %d",&a);
mas=(graf**)malloc(a*sizeof(current));
for (i=0;i<a;i++)//форматированнай ввод списка, ввод строки до 0
{ //0 вводится как отметки конца строки главной вершины
printf("versina %d- ",i+1);
if (d==0) {current=(graf*)malloc(sizeof(graf));
start=current; d=1;} //создание начала списка или прдолжения списка
else {current->next=(graf*)malloc(sizeof(graf));
current=current->next;};
current->num=i+1;
mas[n]=current;n++;
current->ind=0;
do{
current->next=(graf*)malloc(sizeof(graf));
current=current->next;scanf(" %d",¤t->num);
} while (current->num!=0);
}
current->next=NULL; //ссылка на NULL последнего элемента списка
};
void shiri(int d)
{int i,ind=1,n=1;
mas[d-1]->ind=n;
n++;
while(ind==1)
{ind=0;
for(i=0;i<a;i++)
{if(mas[i]->ind==n-1)
{current=mas[i]->next;
while (current->num!=0)
{if(mas[current->num-1]->ind==0)
{mas[current->num-1]->ind=n;
ind=1;}
current=current->next;}
}
}
n++;
}
ind=1;
n=1;
printf("obhod v shirinu\n");
while(ind==1)
{ind=0;
for(i=0;i<a;i++)
{if (mas[i]->ind==n) {printf("%d ",mas[i]->num);ind=1;}
}
n++;
printf("\n");
};
};
void nulind (void)
{current=start;
while (current!=NULL)
{current->ind=0;
current=current->next;
}
};
void glub (int d)
{graf *current1;
current1=mas[d-1]->next;
while (current1->num!=0)
{if (mas[current1->num-1]->ind==0)
{ masg[n]=current1->num;n++;
mas[current1->num-1]->ind=1;
glub(current1->num);
};
current1=current1->next;
};
};
Пример дерева и его представления.
Обход в глубину: 1,2,5,6,3,7,4,8,9.
Обход в ширину: 1,2,3,4,5,67,8,9.
Вывод: Программа позволяет осуществлять проход графа и дерева в глубину и ширину, следовательно выполняет все поставленные перед ней задачи.