Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Основы объектно-ориентированного программирования задач на графах. Учебное пособие
.pdf
3.4. Деструктор класса
21
На каждой итерации цикла создается один одномерный массив, соответствующий одной строке матрицы смежности.
3.4. Деструктор класса
Создав конструктор, который выделяет динамическую память для
двумерного массива, следует сразу же создать деструктор, который удалит
этот массив из динамической памяти. Вспомним, что деструктор – это
функция класса, которая вызывается автоматически, когда объект класса
удаляется из динамической памяти или выходит из области видимости.
В главной функции удалите объект класса Graph из динамической
памяти:
int main()
{
Graph * graph = new Graph;
delete graph;
return 0;
}
До начала удаления объекта класса из динамической памяти операцией
delete будет вызван деструктор класса, который должен удалить массив,
соответствующий матрице смежности, из динамической памяти. Текст деструктора класса Graph приведен ниже:
Graph::~Graph()
{
for(int i=0; i<N;i++)
delete[] Matr[i];
delete[] Matr;
}
Удаление массива должно происходить в обратном порядке. В начале
следует удалить из динамической памяти строки массива:
for(int i=0; i<N; i++)
delete[] Matr[i];

3. Разработка класса для решения задач на графах
22
а затем массив указателей на строки этого массива:
delete[] Matr;
Не забудьте добавить прототип конструктора в описание класса:
class Graph
{
private: int N;
bool **Matr;
public: Graph(int);
~Graph();
};
Запустить программу на выполнение еще рано. Мы забыли про вызов конструктора класса. Если конструктор класса имеет аргументы, то его обязательно надо вызвать. В нашем примере прежде следует ввести количество
вершин графа, а затем передать это значение через аргумент конструктора.
Для этого добавьте следующие строки в главную функцию:
int main()
{
int number; //число вершин графа
cin>>number;
Graph * graph = new Graph(number);
delete graph;
return 0;
}
В операторе
Graph * graph = new Graph(number);
запись (number) соответствует неявному вызову конструктора класса
Graph.
Теперь запустим приложение на выполнение. Если нет ошибок, то
потребуется только ввести с клавиатуры число вершин графа. Если появится окно сообщений, то придется внести исправления в программу.

3.4. Деструктор класса
23
В нашем случае ошибка будет наверняка, так как не подключен файл
iostream.h для того, чтобы можно было использовать объект cin.
Подключите этот заголовочный файл. Получите следующий текст
программы, который внимательно изучите:
//----------------------------------------------------
#pragma hdrstop
#include <iostream.h>
//----------------------------------------------------
class Graph
{
private: int N;
bool **Matr;
public: Graph(int);
~Graph();
};
//----------------------------------------------------
Graph::Graph(int n1)
{
N=n1;
Matr=new bool *[N];
for(int i=0; i<N;i++)
Matr[i]= new bool [N];
}
//----------------------------------------------------
Graph::~Graph()
{
for(int i=0; i<N;i++)
delete[] Matr[i];
delete[] Matr;
}
//----------------------------------------------------
#pragma argsused
int main()

3. Разработка класса для решения задач на графах
24
{
int number;
cin>>number;
Graph * graph = new Graph(number);
delete graph;
return 0;
}
//----------------------------------------------------
3.5. Функции класса
Теперь рассмотрим создание функций класса Graph. Когда вы создаете класс, то не думайте о конкретной задаче на графах. Класс создается
для абстрактного объекта типа Graph. Класс должен описать этот объект.
Чем точнее будет описан объект, тем легче с ним будет работать. Представьте себе абстрактный объект – граф, и подумайте о том, какие операции (действия) можно выполнять с графами и какие параметры имеет объект. Операциям соответствуют функции класса, параметрам объекта –
данные класса.
Прежде всего, необходимо вводить и выводить информацию
о графе – матрицу смежности и количество вершин. Следовательно, в состав класса необходимо включить операции ввода-вывода графа.
Кроме того, в состав класса можно включить, например, решение
следующих простых задач на графах:
проверить, смежны или нет любые две вершины графа;
определить вершины смежные с заданной вершиной;
для заданной вершины графа определить номера всех вершин, не
смежных с ней;
определить вершины смежные одновременно с каждой из двух
заданных вершин графа;
определить вершину графа с наибольшим суммарным весом
смежных с ней ребер;
определить вершины смежные двум заданным вершинам графа;
определить вершины с наибольшей локальной степенью;

3.6. Ввод-вывод матрицы смежности графа
25
определить граф, дополнительный к заданному графу;
для заданной вершины графа определить смежную с ней вершину
с наибольшей локальной степенью;
определить количество ребер графа.
Можно также включить в состав класса решение более сложных за-
дач на графах, примерный перечень которых приведен в прил. 1.
Перечисленные задачи составляют лишь небольшое число задач на
графах. Кроме того, для разных типов графов известны одни и те же задачи. Например, путь между двумя вершинами графа можно определять как
для неориентированных графов, так и ориентированных. Мы не ставим перед собой задачу разработать абсолютно все возможные функции для решения задач на графах. Цель пособия – освоить основные принципы разработки класса для решения задач на графах. Поэтому ограничимся несколькими основными функциями при описании класса Graph.
3.6. Ввод-вывод матрицы смежности графа
Продолжим разработку класса Graph. Создадим функцию
input_Graph()для ввода графа и функцию out_Graph() для вывода
графа. Будем вводить матрицу смежности с клавиатуры, а выводить ее на
экран дисплея. Добавьте в описание класса прототипы этих функций:
class Graph
{
private: int N;
bool **Matr;
public: Graph(int);
~Graph();
void input_Graph();
void out_Graph();
};
Тела этих функций опишете вне тела класса Graph. Функция
input_Graph() ввода матрицы смежности следующая:

3. Разработка класса для решения задач на графах
26
void Graph::input_Graph()
{
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
{
cout << " Matr["<< i <<"]["<< j <<"]=";
cin >> Matr[i][j];
}
}
Функция вывода матрицы смежности out_Graph():
void Graph::out_Graph()
{
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
{
cout << " Matr["<< i <<"]["<< j <<"]=";
cout << Matr[i][j] << endl;
}
}
Работа этих функций должна быть знакома из начального курса С++.
Добавьте в главную функцию вызов этих функций для объекта класса
Graph:
int main()
{
int number;
cin>>number;
Graph * graph = new Graph(number);
graph->input_Graph();
graph->out_Graph();
delete graph;
return 0;
}

3.7. Определение вершин графа, смежных двум заданным вершинам
27
3.7. Определение вершин графа, смежных двум заданным вершинам
Включим в описание класса еще одну функцию для определения
вершин графа, смежных двум заданным вершинам графа (объединение
вершин, смежных каждой из двух заданных вершин графа). Например,
второй и пятой вершинам графа (см. рис. 1) будут одновременно смежны
Первая и Вторая вершины.
Назовем эту функцию adjacency(). По смыслу задачи в этой
функции необходимо знать номера двух вершин графа, которые передадим
с помощью аргументов этой функции.
Рассмотрим функцию класса Graph adjacency():
void Graph::adjacency(int x11, int x22)
{
bool *mas = new bool[N];
for(int i=0; i<N; i++)
if(Matr[x11-1][i] || Matr[x22-1][i]) mas[i]=1;
else mas[i]=0;
mas[x11-1]=0; mas[x22-1]=0;
cout<<"\n Tops "<<x11<<" OR"<<x22<<" adjacency
tops:";
for(int i=0; i<N; i++)
if(mas[i]) cout<< i+1<<” ”;
delete mas;
}
В этой функции создается в динамической памяти дополнительный
одномерный массив mas:
bool *mas = new bool[N];
Затем просматриваются элементы одного и того же столбца для двух строк
массива Matr, которые соответствуют заданным вершинам графа:
for(int i=0; i<N; i++)
if(Matr[x11-1][i] || Matr[x22-1][i]) mas[i]=1;
else mas[i]=0;

3. Разработка класса для решения задач на графах
28
Если хотя бы в одной строке i-й столбец содержит 1, то i-му элементу
вспомогательного массива присваивается значение 1, в противном
случае – 0. Таким образом, в вспомогательный массив заносится 1 в том
случае, если хотя бы одна из заданных вершин смежна с вершиной соответствующей i-му столбцу.
Следующие операторы:
mas[x11-1]=0; mas[x22-1]=0;
необходимы для того, чтобы исключить из решения сами заданные
вершины.
Затем выводятся на экран номера вершин, соответствующих элемен-
там вспомогательного массива, значение которых равно 1:
cout<<"\n Tops "<<x11<<" OR "<<x22<< " adjacency
tops: ";
for(int i=0; i<N; i++)
if(mas[i]) cout<< i+1<<” ”;
В конце функции вспомогательный массив удаляется из динамической памяти:
delete[] mas;
Не забудьте добавить в описание класса прототип функции
adjacency().
Теперь допишите в главной функции операторы для определения
вершин графа, смежных одновременно двум заданным вершинам графа.
Для этого необходимо ввести с клавиатуры значения номеров двух вершин
и вызвать функцию adjacency(), в которую следует передать их с помощью аргументов:
int main()
{
int number;
int x1,x2;
cin>>number;
Graph * graph = new Graph(number);
graph->input_Graph();

3.8. Пример выполнения программы
29
graph->out_Graph();
cout<<" Input number of two tops: ";
cin>>x1>>x2;
graph->adjacency(x1,x2);
delete graph;
getch();
return 0;
}
3.8. Пример выполнения программы
Запустите программу на выполнение. Результат ее работы для простого графа, показанного на рис. 6, матрица смежности которого показана
на рис. 7, представлен на рис. 8.
Рис. 6. Граф Рис. 7. Матрица смежности
Рис. 8. Результат работы программы
1
2
3
1
0
0 1 1
0 0 1
0
1 2 3
1
2
3

3. Разработка класса для решения задач на графах
30
3.9. Программа для работы с графом
//---------------------------------------------------#pragma hdrstop
#include <iostream.h>
#include <conio.h>
//----------------------------------------------------
class Graph
{
private: int N;
bool **Matr;
public: Graph(int);
~Graph();
void input_Graph();
void out_Graph();
void adjacency(int,int);
};
//----------------------------------------------------
Graph::Graph(int n1)
{
N=n1;
Matr=new bool *[N];
for(int i=0; i<N;i++)
Matr[i]= new bool [N];
}
//----------------------------------------------------
Graph::~Graph()
{
for(int i=0; i<N;i++)
delete[] Matr[i];
delete[] Matr;
}
//----------------------------------------------------
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
