- •Лабораторная работа № 1 структура данных дерево
- •Теоретические сведения
- •Синтаксис объявления класса tTreeNode
- •Синтаксис объявления класса tTree
- •Программа работы
- •Контрольные вопросы
- •Лабораторная работа № 2 бинарные деревья
- •Теоретические сведения
- •Синтаксис объявления класса tBinTreeNode
- •Синтаксис объявления класса tBinTree
- •Программа работы
- •Контрольные вопросы
- •Лабораторная работа № 3 бинарные деревья поиска
- •Теоретические сведения
- •Синтаксис объявления класса tFindTreeNode
- •Синтаксис объявления класса tFindTree
- •Программа работы
- •Контрольные вопросы
- •Лабораторная работа № 4 сбалансированные деревья. Пирамида.
- •Теоретические сведения
- •Синтаксис объявления класса tHeap
- •Пирамидальная сортировка
- •Программа работы
- •Контрольные вопросы
- •Лабораторная работа № 5 алгоритмы сортировки данных
- •Теоретические сведения
- •Алгоритмы внутренней сортировки
- •Программа работы
- •Контрольные вопросы
- •Лабораторная работа № 6 структура данных граф
- •Теоретические сведения
- •Программа работы
- •Контрольные вопросы
- •Библиографический список
- •Содержание
Лабораторная работа № 6 структура данных граф
Цель работы: изучить структуру данных граф, разработать класс TGraph для работы с ней и получить практический навык его использования.
Теоретические сведения
Граф (Graph) – это структура данных, представленная в виде списка элементов, у каждого из которых может быть множество наследников и множество родителей.
Граф является обобщенной структурой данных, и на его основе можно построить все предыдущие линейные и нелинейные структуры данных.
Граф представляет собой совокупность вершин (Virteces) соединенных друг с другом ребрами (Edges).
Вершины графа обозначаются буквой V, а сам граф записывается в виде множества его вершин .
Ребра графа обозначаются буквой E, и записываются в виде объединения двух вершин ,
где - указывает начало ребра, - его конец.
Различают два графа:
Направленные графы (орграф);
Ненаправленные графы.
В направленных графах (directed graph или bigraph) существует направление ребра от начальной вершины до конечной вершины. Т.е.
В ненаправленных графах (undirected graph) ребра направлений не имеют. Т.е.
Направленный граф |
Ненаправленный граф |
Путем (Path) – называется объединение трех или более вершин, которые определяют способ прохода от до .
или
Путь из одной вершины в туже самую вершину называется циклом (Cycle).
или
Граф называется сильно связанным (strong connected), если для любой вершины существует путь или ребро для любой другой вершины.
Таким образом в сильно связанных графах существуют пути и .
Граф называется слабо связанным (light connected graph), если существует путь или ребро из одной вершины в любую другую. В слабо связанных графах из одной вершины можно добраться в любую другую, но обратного пути может и не существовать: или .
Strongly connected component – называется часть графа, которая сильно связана.
Способы представления графа
Существует два способа представления графа в памяти компбютера:
с помощью матрицы смежности;
с помощью связанного списка.
1. При представлении графа в виде матрицы смежности все вершины графа помещаются в одномерный список, к которому добавляется двумерная матрица квадратного вида. Пересечение строк и столбцов этой матрицы определяют вес ребра (weight edges). Если ребро существует, то его вес принимают равным 1, если не существует, то 0. Если ребра графа имеют другой вес, то вместо 1 указвается конкретный вес ребра.
Пример
|
|
Достоинства: простота хранения узлов.
Недостатки: в памяти необходимо хранить матрицу смежности даже при условии, что она заполнена не полностью.
2. При использовании связанного списка списка, к каждой вершине добавляется список связанных вершин с их весами.
|
Вершина
|
Список
Нет
|
Достоинства: вв памяти хранятся только те вершины, с которыми связаны данные, а не все вершины графа.
Недостатки: обращение к списку вершин происходит медленнее, чем непосредственная индексация.
Объявление класса TGraph
#include <vector>
using namespace std;
const int MaxSize=25;
template <class T>
class TGraph
{
private:
int GraphSize;
vector<T> Vertexes;
int Edge[MaxSize][MaxSize];
public:
TGraph();
int GetVertexPos(T &Vertex);
int GetWeight(T &Vertex1, T &Vertex2);
void InsertVertex(T &Vertex);
void InsertWeight(T &Vertex1, T &Vertex2, int Weight);
void DeleteVertex(T &Vertex);
void DeleteEdge(T &Vertex1, T &Vertex2);
};
В классе TGraph объявлено три закрытых поля. GraphSize – хранит текущий размер графа. Vertexes – список вершин графа, представленный в виде класса «вектор». Edge — двумерный массив, предназначенный для хранения матрицы смежности, максимальный размер которой определяется заданной константой MaxSize. В открытом разделе предусмотрены: конструктор, метод находящий порядковый номер заданой вершины в списке, метод возвращающий вес ребра между двумя вершинами, метод добавляющий новую вершину в граф, метод устанавливающий ребро между двумя вершинами с указанным весом, метод удаляющий узел графа и метод удаляющий ребро между двумя соответствующим вершинам.
Определение методов класса TGraph
Конструктор
template <class T>
TGraph<T>::TGraph()
{
for (int i=0; i<MaxSize; i++)
for (int j=0; j<MaxSize; j++)
Edge[i][j]=0;
GraphSize=0;
}
Все ребра в матрице смежности принимаются равными 0, и размер графа равен 0.
Поиск текущей позиции вершины
template <class T>
int TGraph<T>::GetVertexPos(T &Vertex)
{
int res=-1;
for (int i=0; i<GraphSize; i++)
if (Vertex[i]==Vertex)
{
res=i;
break;
}
return res;
}
Вначале просматривается весь список вершин и, если текущая вершина совпала с переменной, то возвращается ее позиция. В противном случае - (-1), т.е. Вершина не найдена.
Метод возвращающий вес между двумя вершинами
template <class T>
int TGraph<T>::GetWeight(T &Vertex1, T &Vertex2)
{
int pos1=GetVertexPos(Vertex1), pos2=GetVertexPos(Vertex2);
if (pos1!=-1 && pos2!=-1)
return Edge[pos1][pos2];
else
return 0;
}
Данный метод вначале ищет позиции двух передаваемых вершин. Если обе вершины найдены, то возвращается вес ребра, хранящийся в матрице смежности. В противном случае — 0, говорящий, что ребра нет.
Метод вставки узла
template <class T>
void TGraph<T>::InsertVertex(T &Vertex)
{
if (GraphSize==MaxSize)
throw Exception("Граф переполнен!");
int pos=GetVertexPos(Vertex);
if (pos==-1)
{
Vertex.push_back();
GraphSize++;
}
}
В данном методе вначале проверяется не достиг ли граф максимального рзмера. Если нет, то используется позиция переданной вершины в списке. Если данная вершина не найдена, то она добавляется в конец, а список вершин и размер графа увеличиваются на 1.
Метод задания веса ребра между двумя вершинами
template <class T>
void TGraph<T>::InsertWeight(T &Vertex1, T &Vertex2, int Weight)
{
int pos1=GetVertexPos(Vertex1), pos2=GetVertexPos(Vertex2);
if (pos1!=-1 && pos2!=-1)
Edge[pos1][pos2]=Weight;
else
throw Exception("Не найден узел!");
}
Вначале находятся позиции двух переданных вершин и, если они существуют, то в соответствующую ячейку матрицы смежности присваивается новый вес.
Метод удаления узла
template <class T>
void TGraph<T>::DeleteVertex(T &Vertex)
{
int pos=GetVertexPos(Vertex);
if (pos!=-1)
{
for (int i=pos+1; i<GraphSize; i++)
Vertexes[i-1]=Vertexes[i];
Vertexes.pop_back();
for (int i=pos+1; i<GraphSize; i++)
for (int j=0; j<pos; j++)
Edge[i-1][j]=Edge[i][j];
for (int i=0; i<pos; i++)
for (int j=pos+1; j<GraphSize; j++)
Edge[i][j-1]=Edge[i][j];
for (int i=pos+1; i<GraphSize; i++)
for (int j=pos+1; j<GraphSize; j++)
Edge[i-1][j-1]=Edge[i][j];
for (int i=0; i<GraphSize; i++)
{
Edge[i][GraphSize-1]=0;
Edge[GraphSize-1][i]=0;
}
}
}
Вначале находится позиция удаляемой вершины. Если вершина найдена, то ввсе последующие вершины перемещаются на одну позицию вперед и удаляется вершина из конца списка, уменьшая размер графа на 1. После этого исправляется матрица смежности, которая разбивается на три области:
В области I все строки перемещаются на одну позицию вверх, во II – области влево, в III — строки и столбцы вверх и влево.
Метод удаления узла между двумя вершинами
template <class T>
void TGraph<T>::DeleteEdge(T &Vertex1, T &Vertex2)
{
int pos1=GetVertexPos(Vertex1), pos2=GetVertexPos(Vertex2);
if (pos1!=-1 && pos2!=-1)
Edge[pos1][pos2]=0;
else
throw Exception("Не найден узел!");
}