背景及原理讲解链接: https://blog.youkuaiyun.com/qq_44394952/article/details/122260279.
Warshall.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Warshall
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
RESOURCES += \
image.qrc
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#define Inf 100;
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
int dis[7][7];
void dijkstar(int *c,int m,int a,int b); //dijkstra核心算法
private:
Ui::MainWindow *ui;
public slots:
void show_dijkstra(int i,int j); //dijkstr槽函数,在槽函数中调用核心算法
signals:
void get_number(int i,int j); //定义信号,传递起始结点和目的结点
private slots:
void on_pushButton_clicked();
};
#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qdebug.h"
#define Inf 100 //Inf表示两结点之间没有连通的路径
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit_2->setValidator(new QIntValidator(0,6,this)); //限制目的结点的输入范围为0~6
ui->lineEdit_4->setValidator(new QIntValidator(0,6,this)); //限制起始结点的输入范围为0~6
int c[7][7]= //设置结点间路径长度数组,由于数组不能在类声明的时候初始化,所以用c[][]来初始化dis数组
{
{0,1,2,3,Inf,Inf,Inf},
{1,0,Inf,Inf,Inf,6,Inf},
{2,Inf,0,Inf,5,4,Inf},
{3,Inf,Inf,0,4,Inf,Inf},
{Inf,Inf,5,4,0,Inf,7},
{Inf,6,4,Inf,Inf,0,8},
{Inf,Inf,Inf,Inf,7,8,0},
};
for(int i=0;i<7;i++)
for(int j=0;j<7;j++)
dis[i][j]=c[i][j]; //用c[][]来初始化dis数组
connect(this,SIGNAL(get_number(int,int)),this,SLOT(show_dijkstra(int,int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::dijkstar(int *c, int m, int a, int b)
{
int size = m;
int min = 0;
int u;
int next = a;
int *dis = (int*)malloc(sizeof(int)*size); //为dis数组申请int*size大小的空间
int *book = (int*)malloc(sizeof(int)*size); //为book数组申请int*size大小的空间
int *road = (int*)malloc(sizeof(int)*size); //为road数组申请int*size大小的空间
//road数组初始化
for (int i = 0; i < size - 1; i++)
road[i] = 100;
//dis数组初始化
for (int i = 0; i <= size-1; i++) //保存a点到每个点的距离,0~6,共7个点
{
dis[i] = *(c + a*m + i);
}
//book数组初始化
for (int i = 0; i <= size - 1; i++)
{
book[i] = 0;
}
book[a] = 1;
//dijkstra算法
for (int i = 0; i <= size - 2; i++)
{
min = Inf;
for (int j = 0; j <= size - 1; j++)
{
if (book[j] == 0 && dis[j] < min)
{
min = dis[j];
u = j;
}
}
book[u] = 1;
for (int v = 0; v <= size - 1; v++)
{
if (*(c + u*m + v) < Inf)
{
if (dis[v] > dis[u] + *(c + u*m + v))
{
dis[v] = dis[u] + *(c + u*m + v);
road[v] = u;
}
}
}
}
//输出结果
int outroad = b;
//GUI中显示路径
QString show=QString::number(b,10);
ui->label_8->setText(show);
while (6 >= road[outroad] && road[outroad] >= 0)
{
show=QString::number(road[outroad],8)+"-->"+show;
ui->label_8->setText(show);
outroad = road[outroad];
}
show=QString::number(a,8)+"-->"+show;
ui->label_8->setText(show);
ui->label_9->setText(QString::number(dis[b],10));
//回收空间
free(dis);
free(book);
free(road);
}
void MainWindow::show_dijkstra(int i, int j)
{
dijkstar((int *)dis,7,i,j);
}
void MainWindow::on_pushButton_clicked()
{
emit get_number(ui->lineEdit_4->text().toInt(),ui->lineEdit_2->text().toInt()); //字符串Qstring转化为数int
}