134 lines
3.0 KiB
C++
Executable File
134 lines
3.0 KiB
C++
Executable File
// This is the .cpp file you will edit and turn in.
|
|
// We have provided a skeleton for you,
|
|
// but you must finish it as described in the spec.
|
|
// Also remove these comments here and add your own.
|
|
// TODO: remove this comment header
|
|
|
|
#include "Tour.h"
|
|
#include "Node.h"
|
|
#include "Point.h"
|
|
#include <iostream>
|
|
|
|
Tour::Tour() : m_startNode(nullptr) {}
|
|
|
|
Tour::~Tour() {
|
|
if (m_startNode == nullptr)
|
|
return;
|
|
|
|
Node *node = m_startNode;
|
|
if (node->next == m_startNode) {
|
|
delete node;
|
|
return;
|
|
}
|
|
|
|
do {
|
|
Node *next = node->next;
|
|
delete node;
|
|
node = next;
|
|
} while (node != m_startNode);
|
|
}
|
|
|
|
void Tour::show() const {
|
|
if (m_startNode == nullptr)
|
|
return;
|
|
|
|
Node *node = m_startNode;
|
|
do {
|
|
Point &p = node->point;
|
|
// I'm not using std::endl here to avoid flushing stdout for every
|
|
// iteration.
|
|
std::cout << '(' << p.x << ", " << p.y << ")\n";
|
|
node = node->next;
|
|
} while (node != m_startNode);
|
|
|
|
// Finally, flush!
|
|
std::flush(std::cout);
|
|
}
|
|
|
|
void Tour::draw(QGraphicsScene *scene) const {
|
|
if (m_startNode == nullptr)
|
|
return;
|
|
|
|
Node *node = m_startNode;
|
|
do {
|
|
node->point.drawTo(node->next->point, scene);
|
|
node = node->next;
|
|
} while (node != m_startNode);
|
|
}
|
|
|
|
int Tour::size() const {
|
|
if (m_startNode == nullptr)
|
|
return 0;
|
|
|
|
int count = 0;
|
|
Node *node = m_startNode;
|
|
do {
|
|
count++;
|
|
node = node->next;
|
|
} while (node != m_startNode);
|
|
|
|
return count;
|
|
}
|
|
|
|
double Tour::distance() const {
|
|
if (m_startNode == nullptr)
|
|
return 0;
|
|
|
|
double totalDistance = 0;
|
|
Node *node = m_startNode;
|
|
do {
|
|
totalDistance += node->point.distanceTo(node->next->point);
|
|
node = node->next;
|
|
} while (node != m_startNode);
|
|
|
|
return totalDistance;
|
|
}
|
|
|
|
void Tour::insertNearest(Point p) {
|
|
if (m_startNode == nullptr) {
|
|
m_startNode = new Node(p);
|
|
return;
|
|
}
|
|
|
|
Node *nearest = m_startNode;
|
|
double minDistance = INFINITY;
|
|
|
|
Node *node = m_startNode;
|
|
do {
|
|
double currentDistance = node->point.distanceTo(p);
|
|
if (currentDistance < minDistance) {
|
|
minDistance = currentDistance;
|
|
nearest = node;
|
|
}
|
|
node = node->next;
|
|
} while (node != m_startNode);
|
|
|
|
auto *newNode = new Node(p, nearest->next);
|
|
nearest->next = newNode;
|
|
}
|
|
|
|
void Tour::insertSmallest(Point p) {
|
|
if (m_startNode == nullptr) {
|
|
m_startNode = new Node(p);
|
|
return;
|
|
}
|
|
|
|
Node *bestNode = m_startNode;
|
|
double minIncrease = INFINITY;
|
|
|
|
Node *node = m_startNode;
|
|
do {
|
|
double increase = node->point.distanceTo(p) +
|
|
p.distanceTo(node->next->point) -
|
|
node->point.distanceTo(node->next->point);
|
|
if (increase < minIncrease) {
|
|
minIncrease = increase;
|
|
bestNode = node;
|
|
}
|
|
node = node->next;
|
|
} while (node != m_startNode);
|
|
|
|
auto *newNode = new Node(p, bestNode->next);
|
|
bestNode->next = newNode;
|
|
}
|