要将实现最小生成树问题的C++代码放入相应文件并在Qt平台成功运行,可按以下方式操作:
创建Qt项目
打开Qt Creator,选择“File” -> “New File or Project”,在弹出的对话框中选择“Qt Widgets Application”,然后按照向导完成项目创建。
代码文件安排
头文件(.h):将图和边的类定义、算法声明等代码放入头文件中。例如,创建一个名为graph.h的文件,内容如下:
C++
#ifndef GRAPH_H
#define GRAPH_H
#include <vector>
#include <string>
#include <algorithm>
class Edge {
public:
std::string src, dest;
int weight;
Edge(std::string s, std::string d, int w) : src(s), dest(d), weight(w) {}
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
class Graph {
public:
std::vector<std::string> vertices;
std::vector<Edge> edges;
void addEdge(std::string src, std::string dest, int weight) {
edges.emplace_back(src, dest, weight);
if (std::find(vertices.begin(), vertices.end(), src) == vertices.end()) {
vertices.push_back(src);
}
if (std::find(vertices.begin(), vertices.end(), dest) == vertices.end()) {
vertices.push_back(dest);
}
}
};
std::vector<Edge> kruskal(const Graph& graph);
std::vector<Edge> prim(const Graph& graph, const std::string& start);
#endif // GRAPH_H
源文件(.cpp):将算法的实现代码放入对应的源文件中。创建graph.cpp文件,内容如下:
C++
#include "graph.h"
std::vector<Edge> kruskal(const Graph& graph) {
std::vector<Edge> result;
std::vector<Edge> sortedEdges = graph.edges;
std::sort(sortedEdges.begin(), sortedEdges.end());
std::vector<std::string> parent;
for (const auto& vertex : graph.vertices) {
parent.push_back(vertex);
}
auto find = [&](const std::string& vertex) {
std::string root = vertex;
while (root != parent[std::find(graph.vertices.begin(), graph.vertices.end(), root) - graph.vertices.begin()]) {
root = parent[std::find(graph.vertices.begin(), graph.vertices.end(), root) - graph.vertices.begin()];
}
std::string current = vertex;
while (current != root) {
std::string next = parent[std::find(graph.vertices.begin(), graph.vertices.end(), current) - graph.vertices.begin()];
parent[std::find(graph.vertices.begin(), graph.vertices.end(), current) - graph.vertices.begin()] = root;
current = next;
}
return root;
};
auto unite = [&](const std::string& u, const std::string& v) {
std::string root1 = find(u);
std::string root2 = find(v);
if (root1 != root2) {
parent[std::find(graph.vertices.begin(), graph.vertices.end(), root1) - graph.vertices.begin()] = root2;
}
};
for (const auto& edge : sortedEdges) {
std::string u = edge.src;
std::string v = edge.dest;
if (find(u) != find(v)) {
result.push_back(edge);
unite(u, v);
}
}
return result;
}
std::vector<Edge> prim(const Graph& graph, const std::string& start) {
std::vector<Edge> result;
std::vector<std::string> mstSet;
mstSet.push_back(start);
while (mstSet.size() < graph.vertices.size()) {
Edge minEdge("", "", INT_MAX);
for (const auto& vertex : mstSet) {
for (const auto& edge : graph.edges) {
if ((edge.src == vertex && std::find(mstSet.begin(), mstSet.end(), edge.dest) == mstSet.end()) ||
(edge.dest == vertex && std::find(mstSet.begin(), mstSet.end(), edge.src) == mstSet.end())) {
if (edge.weight < minEdge.weight) {
minEdge = edge;
}
}
}
}
result.push_back(minEdge);
if (std::find(mstSet.begin(), mstSet.end(), minEdge.src) == mstSet.end()) {
mstSet.push_back(minEdge.src);
} else {
mstSet.push_back(minEdge.dest);
}
}
return result;
}
主窗口文件:将图形界面和交互逻辑的代码放入主窗口的头文件和源文件中。mainwindow.h文件内容如下:
C++
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include "graph.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void importFile();
void runKruskal();
void runPrim();
private:
Ui::MainWindow *ui;
Graph graph;
QPushButton *importButton;
QLineEdit *startInput;
QPushButton *kruskalButton;
QPushButton *primButton;
QTextEdit *resultText;
};
#endif // MAINWINDOW_H
mainwindow.cpp文件内容如下:
C++
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
QVBoxLayout *layout = new QVBoxLayout(centralWidget);
importButton = new QPushButton("导入文件", this);
layout->addWidget(importButton);
connect(importButton, &QPushButton::clicked, this, &MainWindow::importFile);
startInput = new QLineEdit(this);
startInput->setPlaceholderText("输入起点城市");
layout->addWidget(startInput);
kruskalButton = new QPushButton("克鲁斯卡尔算法", this);
layout->addWidget(kruskalButton);
connect(kruskalButton, &QPushButton::clicked, this, &MainWindow::runKruskal);
primButton = new QPushButton("普里姆算法", this);
layout->addWidget(primButton);
connect(primButton, &QPushButton::clicked, this, &MainWindow::runPrim);
resultText = new QTextEdit(this);
resultText->setReadOnly(true);
layout->addWidget(resultText);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::importFile() {
QFile file("cities.txt");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
graph.edges.clear();
graph.vertices.clear();
while (!in.atEnd()) {
QString line = in.readLine();
QStringList parts = line.split(",");
if (parts.size() == 3) {
std::string src = parts[0].toStdString();
std::string dest = parts[1].toStdString();
int weight = parts[2].toInt();
graph.addEdge(src, dest, weight);
}
}
file.close();
QMessageBox::information(this, "导入成功", "城市信息导入成功");
} else {
QMessageBox::critical(this, "导入失败", "无法打开文件");
}
}
void MainWindow::runKruskal() {
std::vector<Edge> result = kruskal(graph);
QString output;
for (const auto& edge : result) {
output += QString::fromStdString(edge.src) + " - " + QString::fromStdString(edge.dest) + " : " + QString::number(edge.weight) + "\n";
}
resultText->setPlainText(output);
}
void MainWindow::runPrim() {
std::string start = startInput->text().toStdString();
if (std::find(graph.vertices.begin(), graph.vertices.end(), start) == graph.vertices.end()) {
QMessageBox::critical(this, "输入错误", "起点城市不存在");
return;
}
std::vector<Edge> result = prim(graph, start);
QString output;
for (const auto& edge : result) {
output += QString::fromStdString(edge.src) + " - " + QString::fromStdString(edge.dest) + " : " + QString::number(edge.weight) + "\n";
}
resultText->setPlainText(output);
}
主函数文件:main.cpp文件内容如下:
C++
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
编译和运行
在Qt Creator中,点击“构建” -> “构建项目”,如果没有错误,再点击“运行”,程序将启动并显示图形界面。
然后怎么做