Граф - это некая модель, схема, которая описывает некоторую задачу. Например, схема дорог между городами, связи между компьютерами и т. д. Важным элементом является информация о том, есть или нет связи между парой объектов (называемые вершинам графа), и если есть, то вводится дополнительная информация о связи (называемые ребрами графа): протяженность дороги, стоимость проезда, пропускная способность канала и т. д.
На рисунке представлен граф без стрелочек (называемый неориентированным графом). Если указать стрелочки, т. е. направление, то это будет ориентированный граф:
Чтобы описать граф обычно используют двумерный массив (матрица) или связный список.
1) Матрица инциденций:
строки-номера вершин; столбцы-номера ребер; если от вершины i идет ребро j, то на пересечении i-ой строки с j-ым столбцом стоит ее вес или 1, все остальные значения равны 0.
На рисунке представлен граф без стрелочек (называемый неориентированным графом). Если указать стрелочки, т. е. направление, то это будет ориентированный граф:
Чтобы описать граф обычно используют двумерный массив (матрица) или связный список.
1) Матрица инциденций:
строки-номера вершин; столбцы-номера ребер; если от вершины i идет ребро j, то на пересечении i-ой строки с j-ым столбцом стоит ее вес или 1, все остальные значения равны 0.
Чтобы задать ориентированную дугу необходимо в строки, соответствующие начальной вершине, поставить её вес, а в соответствующие конечной вершине, её вес со знаком минус.
2) Матрица смежности:
строки и столбцы -номера вершин; если из вершины i в вершину j есть ребро, то на пересечении i-ой строки с j-ым столбцом стоит ее вес или 1, все остальные значения равны 0.
Эти два способа занимают много места из-за их разреженности (много нулей).
3) Матрица списка ребер:
в 1-ой строке - номера вершин, из которых есть ребро; во 2-й строке - номера вершин, в которую это ребро направлено; в 3-ей строке - вес ребра.
Если вес не указан, то 3-я строчка не используется.
4) Другой список:
В каждой I-ой строке сначала записывается количество ребер, которые выходят из i-ой вершины, а затем перечисления номеров вершин, к которым эти ребра направлены. Можно и без нулевого столбца.
5) Связный список обычно используется для хранения большего количества информации об объекте или весе. Поле next направляет к следующей вершине, не обязательно соединенной с предыдущей. В поле info - информация о начале списка вершин, к которым есть ребра из данной вершины. Кроме этого в этом списке можно хранить информацию о весе ребер и другую информацию:
1->2->5
|
V
2->1->3->4
|
V
3->2->4->5->6
|
V
4->2->3->6
|
V
5->1->3
|
V
6->3->4
Это похоже на предыдущий список без нулевого столбца и без лишних нулевых элементов. Такой способ наиболее экономичен.
Кроме обычных графов в задачах используют бинарные деревья (ориентированный граф):
Здесь вершина 1 называется корнем, от которого выходят две ветви: левая 2 и правая 3. Вершина 2 является листом дерева, т.к. из него нет ребер, а вершина 3 - подкорнем, у которого тоже есть листья 4 (левое) и 5 (правое).
Такое дерево тоже можно описать в виде матрицы списка ребер:
где
1-й столбец - номера вершин, первый в списке - это корень дерева;
2-й столбец - номера левых вершин;
3-й столбец - номера правых вершин.
Если есть веса ребер, то можно добавить еще 2 столбца.
Или в виде связного списка, у которого вместо поля next есть два поля left и right - указатели на левую и правую вершину.
Немного о типе "связный список" для бинарного дерева:
type
ptrspisok=^spisok;
spisok=record
info: integer;
left: ptrspisok;
right:ptrspisok;
end;
var root:ptrspisok; - указатель на корень дерева;
s:ptrspisok; - указатель на текущий элемент списка.
И для списка ребер (вершин):
type
ptrspisok1=^spisok1;
spisok1=record
info: integer;
ves: real;
next:ptrspisok;
end;
ptrspisok=^spisok;
spisok=record
info: integer;
curr:ptrspisok1;
next:ptrspisok;
end;
var root:ptrspisok; - указатель на начало списка;
s:ptrspisok; - указатель на текущий элемент списка.
Как работать со списком - это тема другого сообщения.
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | -1 | 0 | 1 | -1 | 0 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 1 | 0 | -1 | 1 | 0 |
4 | 0 | 0 | -1 | 0 | 1 | 0 | 0 | 1 |
5 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | -1 |
строки и столбцы -номера вершин; если из вершины i в вершину j есть ребро, то на пересечении i-ой строки с j-ым столбцом стоит ее вес или 1, все остальные значения равны 0.
1 | 2 | 3 | 4 | 5 | 6 | |
1 | 0 | 1 | 0 | 0 | 1 | 0 |
2 | 0 | 0 | 0 | 1 | 0 | 0 |
3 | 0 | 0 | 0 | 0 | 0 | 1 |
4 | 0 | 0 | 1 | 0 | 0 | 1 |
5 | 1 | 0 | 1 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 | 0 |
Эти два способа занимают много места из-за их разреженности (много нулей).
3) Матрица списка ребер:
в 1-ой строке - номера вершин, из которых есть ребро; во 2-й строке - номера вершин, в которую это ребро направлено; в 3-ей строке - вес ребра.
1 | 2 | 3 | 4 | 5 | 6 | 7 | |
1 | 1 | 1 | 2 | 2 | 3 | 3 | 3 |
2 | 2 | 5 | 3 | 4 | 4 | 5 | 6 |
4) Другой список:
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
1 | 2 | 2 | 5 | 0 | 0 | 0 | 0 |
2 | 3 | 1 | 3 | 4 | 0 | 0 | 0 |
3 | 4 | 2 | 4 | 5 | 6 | 0 | 0 |
4 | 3 | 2 | 3 | 6 | 0 | 0 | 0 |
5 | 2 | 1 | 3 | 0 | 0 | 0 | 0 |
6 | 2 | 3 | 4 | 0 | 0 | 0 | 0 |
В каждой I-ой строке сначала записывается количество ребер, которые выходят из i-ой вершины, а затем перечисления номеров вершин, к которым эти ребра направлены. Можно и без нулевого столбца.
5) Связный список обычно используется для хранения большего количества информации об объекте или весе. Поле next направляет к следующей вершине, не обязательно соединенной с предыдущей. В поле info - информация о начале списка вершин, к которым есть ребра из данной вершины. Кроме этого в этом списке можно хранить информацию о весе ребер и другую информацию:
1->2->5
|
V
2->1->3->4
|
V
3->2->4->5->6
|
V
4->2->3->6
|
V
5->1->3
|
V
6->3->4
Это похоже на предыдущий список без нулевого столбца и без лишних нулевых элементов. Такой способ наиболее экономичен.
Кроме обычных графов в задачах используют бинарные деревья (ориентированный граф):
Здесь вершина 1 называется корнем, от которого выходят две ветви: левая 2 и правая 3. Вершина 2 является листом дерева, т.к. из него нет ребер, а вершина 3 - подкорнем, у которого тоже есть листья 4 (левое) и 5 (правое).
Такое дерево тоже можно описать в виде матрицы списка ребер:
1 | 2 | 3 | |
1 | 1 | 2 | 3 |
2 | 2 | 0 | 0 |
3 | 3 | 4 | 5 |
4 | 4 | 0 | 0 |
5 | 5 | 0 | 0 |
1-й столбец - номера вершин, первый в списке - это корень дерева;
2-й столбец - номера левых вершин;
3-й столбец - номера правых вершин.
Если есть веса ребер, то можно добавить еще 2 столбца.
Или в виде связного списка, у которого вместо поля next есть два поля left и right - указатели на левую и правую вершину.
Немного о типе "связный список" для бинарного дерева:
type
ptrspisok=^spisok;
spisok=record
info: integer;
left: ptrspisok;
right:ptrspisok;
end;
var root:ptrspisok; - указатель на корень дерева;
s:ptrspisok; - указатель на текущий элемент списка.
И для списка ребер (вершин):
type
ptrspisok1=^spisok1;
spisok1=record
info: integer;
ves: real;
next:ptrspisok;
end;
ptrspisok=^spisok;
spisok=record
info: integer;
curr:ptrspisok1;
next:ptrspisok;
end;
var root:ptrspisok; - указатель на начало списка;
s:ptrspisok; - указатель на текущий элемент списка.
Как работать со списком - это тема другого сообщения.
Комментариев нет:
Отправить комментарий