Qt 多线程编程、自动排序
需求: QT产生随机数10000个 通过多线程(为了是主页面不卡顿) 一个线程冒泡排序、一个线程快速排序,看看哪个算法更快。
程序运行结果是这样的

mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QVector>
//生成随机数
class Generate : public QThread
{
Q_OBJECT
public:
explicit Generate(QObject *parent = nullptr);
//槽函数用来接收主线程给的num值
void recvNum(int num);
//受保护的
protected:
void run() override;
//信号
signals:
void sendArray(QVector<int>);
private:
int m_num;
};
//冒泡排序
class BubbleSort : public QThread
{
Q_OBJECT
public:
explicit BubbleSort(QObject *parent = nullptr);
void recvArray(QVector<int> list);
protected:
void run() override;
signals:
void finish(QVector<int> num);
private:
QVector<int> m_list;
};
//快速排序
class QuickSort : public QThread
{
Q_OBJECT
public:
explicit QuickSort(QObject *parent = nullptr);
void recvArray(QVector<int> list);
protected:
void run() override;
private:
void quickSort(QVector<int> &list, int l, int r);
signals:
void finish(QVector<int> num);
private:
QVector<int> m_list;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QElapsedTimer>
#include <QDebug>
Generate::Generate(QObject *parent) : QThread(parent)
{
}
void Generate::recvNum(int num){
m_num = num;
}
void Generate::run()
{
qDebug()<<"生成随机数的线程地址:"<<QThread::currentThread();
QElapsedTimer time;
QVector<int> list;
//开始时间
time.start();
for(int i=0; i < m_num; i++){
//qrand()%100000 对10万取余、生成10万以内的随机数
list.push_back(qrand()%100000);
}
//总用时
int milsec = time.elapsed();
qDebug()<<"生成"<<m_num<<"个随机数总用时间:"<<milsec<<"毫秒";
//发送数据List通过sendArray这个方法
emit sendArray(list);
}
BubbleSort::BubbleSort(QObject *parent) : QThread(parent)
{
}
//接受线程发送来的 STL容器vector
void BubbleSort::recvArray(QVector<int> list)
{
m_list = list;
}
void BubbleSort::run()
{
qDebug() << "冒泡排序的线程的线程地址: " << QThread::currentThread();
QElapsedTimer time;
time.start();
int temp;
for(int i=0; i<m_list.size(); ++i)
{
for(int j=0; j<m_list.size()-i-1; ++j)
{
if(m_list[j] > m_list[j+1])
{
temp = m_list[j];
m_list[j] = m_list[j+1];
m_list[j+1] = temp;
}
}
}
int milsec = time.elapsed();
qDebug() << "冒泡排序用时" << milsec << "毫秒";
emit finish(m_list);
}
QuickSort::QuickSort(QObject *parent) : QThread(parent)
{
}
void QuickSort::recvArray(QVector<int> list)
{
m_list = list;
}
void QuickSort::run()
{
qDebug() << "快速排序的线程的线程地址: " << QThread::currentThread();
QElapsedTimer time;
time.start();
quickSort(m_list, 0, m_list.size()-1);
int milsec = time.elapsed();
qDebug() << "快速排序用时" << milsec << "毫秒";
emit finish(m_list);
}
void QuickSort::quickSort(QVector<int> &s, int l, int r)
{
if (l < r)
{
int i = l, j = r;
// 拿出第一个元素, 保存到x中,第一个位置成为一个坑
int x = s[l];
while (i < j)
{
// 从右向左找小于x的数
while (i < j && s[j] >= x)
{
//左移, 直到遇到小于等于x的数
j--;
}
if (i < j)
{
//将右侧找到的小于x的元素放入左侧坑中, 右侧出现一个坑
//左侧元素索引后移
s[i++] = s[j];
}
// 从左向右找大于等于x的数
while (i < j && s[i] < x)
{
//右移, 直到遇到大于x的数
i++;
}
if (i < j)
{
//将左侧找到的元素放入右侧坑中, 左侧出现一个坑
//右侧元素索引向前移动
s[j--] = s[i];
}
}
//此时 i=j,将保存在x中的数填入坑中
s[i] = x;
quickSort(s, l, i - 1); // 递归调用
quickSort(s, i + 1, r);
}
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
signals:
//主线程发送给子线程的信号、产生多少个随机数
void starting(int num);
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建子线程对象
Generate* gen = new Generate(this);
BubbleSort* bubble = new BubbleSort(this);
QuickSort* quick = new QuickSort(this);
/*
信号槽、当程序运行开始、
this当前程序
&Widget当前的窗口类,
gen 生成随机数的子进程对象、
需要调用recvNum槽函数接受主窗口发来的生成多少随机数
*/
connect(this,&Widget::starting,gen,&Generate::recvNum);
// connect(this,SIGNAL(starting(int)),gen,SLOT(recvNum(int)));
//启动子线程
connect(ui->start,&QPushButton::clicked,this,[=](){
//子线程需要产生多少个随机数
emit starting(10000);
gen->start();
});
//发送QVector容器 给冒泡和快拍两个
connect(gen, &Generate::sendArray, bubble, &BubbleSort::recvArray);
connect(gen, &Generate::sendArray, quick, &QuickSort::recvArray);
//拿到主线程发过来的随机数、通过sendArray发过来
connect(gen,&Generate::sendArray,this,[=](QVector<int> list){
bubble->start();
quick->start();
for(int i=0; i<list.size();++i)
{
ui->randomList->addItem(QString::number(list.at(i)));
}
});
connect(bubble, &BubbleSort::finish, this, [=](QVector<int> list){
for(int i=0; i<list.size(); ++i)
{
ui->bubbleList->addItem(QString::number(list.at(i)));
}
});
connect(quick, &QuickSort::finish, this, [=](QVector<int> list){
for(int i=0; i<list.size(); ++i)
{
ui->quickList->addItem(QString::number(list.at(i)));
}
});
}
Widget::~Widget()
{
delete ui;
}
浙公网安备 33010602011771号