Студопедия — Пример 3. Анализ временной сложности:
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Пример 3. Анализ временной сложности:






Исходный граф:


 

Граф после удаления:

Анализ временной сложности:

Воспользовавшись формулой 1, рассчитаем временную сложность программы для данного примера (количество дуг M = 181, , N = 77):

7601 проход по циклам.

Анализ ёмкостной сложности:

В данном примере количество дуг M = 181, количество вершин N = 77. Исходя из этого, вычислим ёмкостную сложность программы для данного примера по формуле 2:

3309 байт памяти.

Результаты работы программы:


 


 


 




 


 

7. Исходный код программы:

#include "stdafx.h"

#include <iostream>

#include <fstream>

#include <string>

#include <Windows.h>

 

using namespace std;

 

struct ArcGraph {

int outVertexId;

int inVertexId;

};

 

struct DirectedGraph {

ArcGraph oneArc;

DirectedGraph *previousArc;

DirectedGraph *nextArc;

};

 

void _input(int &var) {

int BAD_STATE = 2;

 

do {

cin.clear();

cin.sync();

 

cin >> var;

} while(cin.rdstate() == BAD_STATE);

}

 

void _input(char &output, char mode = 'b') {

const char OUTPUT_MODE = 'o', ASK_MODE = 'b', MAIN_MODE = 'm', SOME_ACTIONS_MODE = 's';

bool successfulInput;

 

do {

cin.sync();

 

cin >> output;

if(output == 'e') exit(0);

 

switch(mode) {

case OUTPUT_MODE: successfulInput = (output == 'f' || output == 's'); break;

case ASK_MODE: successfulInput = (output == 'y' || output == 'n'); break;

case MAIN_MODE: successfulInput = (output == 'p' || output == 'm' || output == 'd' || output == 'r'); break;

case SOME_ACTIONS_MODE: successfulInput = (output == 'p' || output == 'm' || output == 's' || output == 'r'); break;

}

} while(!successfulInput);

}

 

void _input(string &var) {

cin.sync();

 

getline(cin, var);

}

 

bool fileExists(string fileName) {

return (ifstream(fileName)!= NULL);

}

 

void main() {

setlocale(LC_ALL, "Russian");

system("cls");

 

static DirectedGraph *firstArc, *sideNode;

 

static ostream *out;

static fstream fileForOutput;

static string fileForOutputName;

 

static short CURRENT_STAGE = 0;

static int vertexWithMaxLevel, maxLevel, NUM_VERTEX = 0;

static bool **adjacencyMatrix, fileOutput;

static char action;

 

const static short START_EXECUTION = 0, INPUT_DATA = 1, THE_MAIN_PART = 2, SOME_ACTIONS_PERFORMED = 3;

const static char ASK_MODE = 'b', MAIN_MODE = 'm', SOME_ACTIONS_MODE = 's',

YES = 'y', NO = 'n',

ON_THE_SCREEN = 's', INTO_A_FILE = 'f',

FOR_INPUT = 'i', FOR_OUTPUT = 'o', FOR_APPEND = 'a',

PRINT_NEIBORHOODS = 'p', MAKE_ADJACENCY_MATRIX = 'm', DELETE_VERTEX = 'd', RESTART_PROGRAM = 'r', SAVE_NEW_GRAPH = 's', EXIT = 'e';

 

DirectedGraph *assembleGraph(int &NUM_VERTEX, ostream *stream);

fstream openFile(string fileName, char mode);

int findVertexAndPrintNewList(DirectedGraph *firstNode, int NUM_VERTEX, int &maxLevel, ostream *stream);

bool **completeAdjacencyMatrix(DirectedGraph *firstNode, int NUM_VERTEX);

bool saveGraph(string fileName, DirectedGraph *firstNode, int NUM_VERTEX);

void removeAdjacentVertex(DirectedGraph *&firstArc, int NUM_VERTEX, int vertexId, int vertexLevel);

void removeNode(DirectedGraph *node, DirectedGraph *&firstNode);

void printNeiborhoodsList(DirectedGraph *firstNode, ostream *stream, int NUM_VERTEX, bool saveMode, string title = "");

void printMatrix(bool **matrix, int dimension, ostream *stream, string title = "");

void clearMatrix(bool **matrix, int dimention);

 

switch(CURRENT_STAGE) {

case START_EXECUTION:

cout << "Режим ввода данных (f - в файл, s - на экран, e - выход): ";

_input(action, FOR_OUTPUT);

switch(action) {

case ON_THE_SCREEN:

out = &cout;

fileOutput = false;

break;

case INTO_A_FILE:

cout << "Имя файла для записи (расширение не требуется): ";

_input(fileForOutputName);

 

if(fileExists("output/"+fileForOutputName+".txt"))

fileForOutput = openFile("output/"+fileForOutputName+".txt", FOR_APPEND);

else

fileForOutput = openFile("output/"+fileForOutputName+".txt", FOR_OUTPUT);

 

out = &fileForOutput;

fileOutput = true;

break;

}

CURRENT_STAGE = INPUT_DATA;

break;

case INPUT_DATA:

firstArc = assembleGraph(NUM_VERTEX, out);

CURRENT_STAGE = THE_MAIN_PART;

break;

case THE_MAIN_PART:

cout << "Список доступных действий:" << endl;

cout << PRINT_NEIBORHOODS << " - вывести список окрестностей" << endl;

cout << MAKE_ADJACENCY_MATRIX << " - составить и вывести матрицу смежности" << endl;

cout << DELETE_VERTEX << " - удалить смежные с вершиной, имеющей наибольшую степень исхода, вершины" << endl;

cout << RESTART_PROGRAM << " - начать выполнение программы сначала" << endl;

cout << EXIT << " - выход" << endl;

_input(action, MAIN_MODE);

switch(action) {

case PRINT_NEIBORHOODS:

printNeiborhoodsList(firstArc, out, NUM_VERTEX, false, "Граф задан следующим списком окрестностей:");

*out << endl << endl;

if(fileOutput)

cout << "Список окрестностей исходного графа записан в файл." << endl;

break;

case MAKE_ADJACENCY_MATRIX:

adjacencyMatrix = completeAdjacencyMatrix(firstArc, NUM_VERTEX);

printMatrix(adjacencyMatrix, NUM_VERTEX, out, "Матрица смежности исходного графа: ");

clearMatrix(adjacencyMatrix, NUM_VERTEX);

*out << endl << endl;

if(fileOutput)

cout << "Матрица смежности исходного графа записана в файл." << endl;

break;

case DELETE_VERTEX:

vertexWithMaxLevel = findVertexAndPrintNewList(firstArc, NUM_VERTEX, maxLevel, out);

*out << endl;

NUM_VERTEX -= maxLevel;

removeAdjacentVertex(firstArc, NUM_VERTEX, vertexWithMaxLevel, maxLevel);

if(fileOutput)

cout << "Вершины, смежные с вершиной, имеющей максимальную степень исхода, удалены," << endl

<< "Степени исхода всех вершин записаны в файл." << endl;

CURRENT_STAGE = SOME_ACTIONS_PERFORMED;

break;

case RESTART_PROGRAM:

while(firstArc!= NULL) {

sideNode = firstArc;

firstArc = firstArc->nextArc;

delete sideNode;

}

 

if(fileOutput) {

fileForOutput.close();

*out << endl << endl;

cout << "Запись в файл успешно завершена!" << endl;

}

CURRENT_STAGE = START_EXECUTION;

break;

}

break;

case SOME_ACTIONS_PERFORMED:

cout << "Список доступных действий:" << endl;

cout << PRINT_NEIBORHOODS << " - вывести список окрестностей" << endl;

cout << MAKE_ADJACENCY_MATRIX << " - соствить и вывести матрицу смежности" << endl;

cout << SAVE_NEW_GRAPH << " - сохранить новый граф" << endl;

cout << RESTART_PROGRAM << " - начать выполнение программы сначала" << endl;

cout << EXIT << " - выход" << endl;

_input(action, SOME_ACTIONS_MODE);

switch(action) {

case PRINT_NEIBORHOODS:

printNeiborhoodsList(firstArc, out, NUM_VERTEX, false, "Список окрестностей графа после удаления вершин, смежных с вершиной, имеющей максимальную степень исхода:");

*out << endl << endl;

if(fileOutput)

cout << "Список окрестностей нового графа записан в файл." << endl;

break;

case MAKE_ADJACENCY_MATRIX:

adjacencyMatrix = completeAdjacencyMatrix(firstArc, NUM_VERTEX);

printMatrix(adjacencyMatrix, NUM_VERTEX, out, "Матрица смежности нового графа: ");

clearMatrix(adjacencyMatrix, NUM_VERTEX);

*out << endl << endl;

if(fileOutput)

cout << "Матрица смежности нового графа записана в файл." << endl;

break;

case SAVE_NEW_GRAPH:

cout << "Введите имя нового графа: ";

_input(fileForOutputName);

if(!saveGraph(fileForOutputName, firstArc, NUM_VERTEX))

cout << "Граф с таким именем " << fileForOutputName << " уже существует!" << endl;

else

cout << "Сохранение графа произведено успешно." << endl;

break;

case RESTART_PROGRAM:

while(firstArc!= NULL) {

sideNode = firstArc;

firstArc = firstArc->nextArc;

delete sideNode;

}

 

if(fileOutput) {

fileForOutput.close();

*out << endl << endl;

cout << "Запись в файл успешно завершена!" << endl;

}

CURRENT_STAGE = START_EXECUTION;

break;

}

}

 

system("pause");

main();

}

 

DirectedGraph *assembleGraph(int &NUM_VERTEX, ostream *stream) {

DirectedGraph *firstNode = NULL, *lastNode = NULL, *currentNode;

 

bool getArcData(string graphName, int &NUM_VERTEX, DirectedGraph *&lastNode, ostream *stream = &cout);

 

string graphName;

 

cout << "Имя графа: ";

_input(graphName);

 

if(getArcData(graphName, NUM_VERTEX, firstNode, stream)) {

currentNode = firstNode;

 

while(getArcData(graphName, NUM_VERTEX, lastNode)) {

lastNode->previousArc = currentNode;

lastNode->nextArc = NULL;

 

currentNode->nextArc = lastNode;

currentNode = lastNode;

}

}

 

return firstNode;

}

 

bool getArcData(string graphName, int &NUM_VERTEX, DirectedGraph *&lastNode, ostream *stream = &cout) {

static fstream fileForReadGraph;

string filePath = "graphs/";

 

int inVertexId;

static int counter = 0;

char sideChar;

static bool firstIn = true;

 

bool fileExists(string fileName);

fstream openFile(string fileName, char mode);

 

if(firstIn) {

if(!fileExists(filePath+graphName+".txt")) {

cout << "Графа с таким именем не существует!" << endl << "Будет загружен стандартный файл..." << endl;

graphName = "default";

}

fileForReadGraph = openFile(filePath+graphName+".txt", 'i');

 

*stream << "Граф " << graphName << endl;

 

firstIn = false;

counter++;

}

if(fileForReadGraph.eof()) {

firstIn = true;

NUM_VERTEX = counter;

counter = 0;

fileForReadGraph.close();

return false;

}

 

lastNode = (DirectedGraph*) new (DirectedGraph);

lastNode->previousArc = NULL;

lastNode->nextArc = NULL;

if(lastNode == NULL) {

cout << "Память не выделилась!" << endl << "Выполнение программы завершено...";

Sleep(1000);

exit(1);

}

 

fileForReadGraph >> inVertexId;

 

lastNode->oneArc.inVertexId = inVertexId;

lastNode->oneArc.outVertexId = counter;

 

sideChar = fileForReadGraph.get();

 

if(sideChar == '\n')

counter++;

 

return true;

}

 

int findVertexAndPrintNewList(DirectedGraph *firstNode, int NUM_VERTEX, int &maxLevelOfVertex, ostream *stream) {

int counter, inVertexCounter, vertexWithMaxLevel = 0;

 

maxLevelOfVertex = 0;

for(counter = 1; counter <= NUM_VERTEX; counter++) {

inVertexCounter = 0;

while((firstNode!= NULL) && (firstNode->oneArc.outVertexId == counter)) {

inVertexCounter++;

firstNode = firstNode->nextArc;

}

*stream << "Степень исхода вершины " << counter << ": " << inVertexCounter << endl;

 

if(inVertexCounter > maxLevelOfVertex) {

maxLevelOfVertex = inVertexCounter;

vertexWithMaxLevel = counter;

}

}

 

*stream << "Вершина с максимальной степенью исхода: " << vertexWithMaxLevel << endl;

 

return vertexWithMaxLevel;

}

 

int foundInArray(int value, int *arr, int rightBound) {

int counter, middle, leftBound = 0;

 

if((value > arr[rightBound]) || (value < arr[leftBound]))

return -1;

 

counter = 0;

while((rightBound-leftBound) > 1) {

middle = (rightBound+leftBound)/2;

 

if(arr[middle] < value)

leftBound = middle;

else

rightBound = middle;

}

 

for(counter = 0; counter <= rightBound; counter++) {

if(arr[counter] == value)

return counter;

}

 

return -1;

}

 

fstream openFile(string fileName, char mode) {

fstream filePointer;

 

switch(mode) {

case 'i': filePointer.open(fileName, ios_base::in); break;

case 'o': filePointer.open(fileName, ios_base::out); break;

case 'a': filePointer.open(fileName, ios_base::app); break;

}

 

return filePointer;

}

 

void removeNode(DirectedGraph *node, DirectedGraph *&firstNode) {

if((node->previousArc!= NULL) && (node->nextArc!= NULL)) {

node->previousArc->nextArc = node->nextArc;

node->nextArc->previousArc = node->previousArc;

} else if((node->previousArc == NULL) && (node->nextArc!= NULL)) {

node->nextArc->previousArc = NULL;

firstNode = node->nextArc;

} else if((node->previousArc!= NULL) && (node->nextArc == NULL)) {

node->previousArc->nextArc = NULL;

} else if((node->previousArc == NULL) && (node->nextArc == NULL)) {

firstNode = NULL;

}

 

delete node;

}

 

bool saveGraph(string fileName, DirectedGraph *firstNode, int NUM_VERTEX) {

bool fileExists(string fileName);

void printNeiborhoodsList(DirectedGraph *firstNode, ostream *stream, int NUM_VERTEX, bool saveMode, string title = "");

fstream openFile(string fileName, char mode);

 

if(fileExists("graphs/"+fileName+".txt")) return false;

 

fstream file;

file = openFile("graphs/"+fileName+".txt", 'o');

printNeiborhoodsList(firstNode, &file, NUM_VERTEX, true);

return true;

}

 

void removeAdjacentVertex(DirectedGraph *&firstArc, int NUM_VERTEX, int vertexId, int vertexLevel) {

DirectedGraph *currentNode, *nodePointer, *sidePointer;

int counter, currentId, *adjacentVertex, *newVertexId, NOT_FOUND = -1;

bool noOneBefore;

 

void removeNode(DirectedGraph *node, DirectedGraph *&firstNode);

int foundInArray(int value, int *arr, int rightBound);

 

currentNode = firstArc;

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId!= vertexId))

currentNode = currentNode->nextArc;

 

counter = 1;

adjacentVertex = new int [vertexLevel];

adjacentVertex[0] = currentNode->oneArc.inVertexId;

currentNode->oneArc.inVertexId = 0;

currentNode = currentNode->nextArc;

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId == vertexId)) {

adjacentVertex[counter] = currentNode->oneArc.inVertexId;

nodePointer = currentNode;

currentNode = currentNode->nextArc;

removeNode(nodePointer, firstArc);

counter++;

}

 

currentNode = firstArc;

while(currentNode!= NULL) {

currentId = currentNode->oneArc.outVertexId;

if(foundInArray(currentId, adjacentVertex, vertexLevel-1)!= NOT_FOUND) {

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId == currentId)) {

nodePointer = currentNode;

currentNode = currentNode->nextArc;

removeNode(nodePointer, firstArc);

}

continue;

}

 

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId == currentId))

currentNode = currentNode->nextArc;

}

 

currentNode = firstArc;

newVertexId = new int [NUM_VERTEX];

counter = 0;

while(currentNode!= NULL) {

newVertexId[counter] = currentNode->oneArc.outVertexId;

 

if(currentNode->oneArc.inVertexId!= 0) {

noOneBefore = true;

sidePointer = NULL;

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId == newVertexId[counter])) {

currentNode->oneArc.outVertexId = counter+1;

if(sidePointer!= NULL) {

removeNode(sidePointer, firstArc);

sidePointer = NULL;

}

 

if(foundInArray(currentNode->oneArc.inVertexId, adjacentVertex, vertexLevel-1)!= NOT_FOUND) {

if(noOneBefore) {

currentNode->oneArc.inVertexId = 0;

sidePointer = currentNode;

currentNode = currentNode->nextArc;

} else {

nodePointer = currentNode;

currentNode = currentNode->nextArc;

removeNode(nodePointer, firstArc);

}

 

continue;

}

 

if(noOneBefore)

noOneBefore = false;

currentNode = currentNode->nextArc;

}

} else {

currentNode->oneArc.outVertexId = counter+1;

currentNode = currentNode->nextArc;

}

 

counter++;

}

 

currentNode = firstArc;

while(currentNode!= NULL) {

if(currentNode->oneArc.inVertexId == 0) {

currentNode = currentNode->nextArc;

continue;

}

 

currentId = currentNode->oneArc.outVertexId;

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId == currentId)) {

currentNode->oneArc.inVertexId = foundInArray(currentNode->oneArc.inVertexId, newVertexId, NUM_VERTEX-1)+1;

currentNode = currentNode->nextArc;

}

}

}

 

void printNeiborhoodsList(DirectedGraph *firstNode, ostream *stream, int NUM_VERTEX, bool saveMode, string title = "") {

DirectedGraph *currentNode = firstNode;

int currentVertex;

 

if(!title.empty())

*stream << title;

 

if(saveMode) {

while(currentNode!= NULL) {

currentVertex = currentNode->oneArc.outVertexId;

*stream << endl << currentNode->oneArc.inVertexId;

currentNode = currentNode->nextArc;

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId == currentVertex)) {

*stream << ' ' << currentNode->oneArc.inVertexId;

currentNode = currentNode->nextArc;

}

}

 

} else {

while(currentNode!= NULL) {

*stream << endl << (currentVertex = currentNode->oneArc.outVertexId) << ": ";

 

*stream << currentNode->oneArc.inVertexId;

currentNode = currentNode->nextArc;

while((currentNode!= NULL) && (currentNode->oneArc.outVertexId == currentVertex)) {

*stream << ' ' << currentNode->oneArc.inVertexId;

currentNode = currentNode->nextArc;

}

}

}

}

 

bool **completeAdjacencyMatrix(DirectedGraph *firstNode, int NUM_VERTEX) {

DirectedGraph *currentNode = firstNode;

int currentId, rowCounter, colCounter;

bool **adjacencyMatrix = new bool* [NUM_VERTEX];

 

for(rowCounter = 0; rowCounter < NUM_VERTEX; rowCounter++) {

adjacencyMatrix[rowCounter] = new bool [NUM_VERTEX];

for(colCounter = 0; colCounter < NUM_VERTEX; colCounter++)

adjacencyMatrix[rowCounter][colCounter] = false;

}

currentNode = firstNode;

 

while(currentNode!= NULL) {

if(currentNode->oneArc.inVertexId!= 0)

adjacencyMatrix[currentNode->oneArc.outVertexId-1][currentNode->oneArc.inVertexId-1] = true;

 

currentNode = currentNode->nextArc;

}

 

return adjacencyMatrix;

}

 

void printMatrix(bool **matrix, int dimension, ostream *stream, string title = "") {

int rowCounter, colCounter;

 

if(!title.empty())

*stream << title;

 

for(rowCounter = 0; rowCounter < dimension; rowCounter++) {

*stream << endl << ' ' << matrix[rowCounter][0];

for(colCounter = 1; colCounter < dimension; colCounter++) {

*stream << ' ' << matrix[rowCounter][colCounter];

}

}

}

 

void clearMatrix(bool **matrix, int dimention) {

for(int counter = 0; counter < dimention; counter++)

delete [] matrix[counter];

 

delete [] matrix;

}







Дата добавления: 2015-06-15; просмотров: 461. Нарушение авторских прав; Мы поможем в написании вашей работы!



Картограммы и картодиаграммы Картограммы и картодиаграммы применяются для изображения географической характеристики изучаемых явлений...

Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...

Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

Типовые ситуационные задачи. Задача 1.У больного А., 20 лет, с детства отмечается повышенное АД, уровень которого в настоящее время составляет 180-200/110-120 мм рт Задача 1.У больного А., 20 лет, с детства отмечается повышенное АД, уровень которого в настоящее время составляет 180-200/110-120 мм рт. ст. Влияние психоэмоциональных факторов отсутствует. Колебаний АД практически нет. Головной боли нет. Нормализовать...

Эндоскопическая диагностика язвенной болезни желудка, гастрита, опухоли Хронический гастрит - понятие клинико-анатомическое, характеризующееся определенными патоморфологическими изменениями слизистой оболочки желудка - неспецифическим воспалительным процессом...

Признаки классификации безопасности Можно выделить следующие признаки классификации безопасности. 1. По признаку масштабности принято различать следующие относительно самостоятельные геополитические уровни и виды безопасности. 1.1. Международная безопасность (глобальная и...

ТРАНСПОРТНАЯ ИММОБИЛИЗАЦИЯ   Под транспортной иммобилизацией понимают мероприятия, направленные на обеспечение покоя в поврежденном участке тела и близлежащих к нему суставах на период перевозки пострадавшего в лечебное учреждение...

Кишечный шов (Ламбера, Альберта, Шмидена, Матешука) Кишечный шов– это способ соединения кишечной стенки. В основе кишечного шва лежит принцип футлярного строения кишечной стенки...

Принципы резекции желудка по типу Бильрот 1, Бильрот 2; операция Гофмейстера-Финстерера. Гастрэктомия Резекция желудка – удаление части желудка: а) дистальная – удаляют 2/3 желудка б) проксимальная – удаляют 95% желудка. Показания...

Studopedia.info - Студопедия - 2014-2024 год . (0.009 сек.) русская версия | украинская версия