之前写了几个排序算法,然后看到别人将排序算法的过程可视化出来,所以就想尝试一下,然后就用Qt简单写了个界面,用QImage和QPainter来画图显示,代码比较简单。
我的想法是画图的时候,图像的X轴对应数组的,然后画垂直线,线的高度就是数组元素值的大小。首先需要一个画整个数组的函数,这个函数要将数组整个画到图像上,背景取黑色,然后线取绿色,为了可视化,将图像的大小设置为宽度数组的元素个数乘以10加10,高度为数组元素最大值乘以10加50,线的宽度为8,这些值都是可以调整的,然后每条线之间要有一定间隔,不然都混在一起了:
void QtSort::drawArray2QImg(int low, int high)
{
if (NULL == m_pNum || NULL == m_pSortImg)
{
return;
}
m_pSortImg->fill(Qt::black);
QPainter painter(this);
QPen pen;
pen.setColor(Qt::green);
pen.setWidth(dWidth);
QFont font;
font.setPointSize(10);
font.setBold(true);
painter.begin(m_pSortImg);
painter.setPen(pen);
painter.setFont(font);
for (int i = low; i < high; i++)
{
pen.setColor(Qt::green);
painter.setPen(pen);
QPoint pnt1 = QPoint(i * dMul + dWidth / 2 + 4, dLen * dMul + 50);
QPoint pnt2 = QPoint(i * dMul + dWidth / 2 + 4, dLen * dMul + 50 - m_pNum[i] * dMul + 5);
painter.drawLine(pnt1, pnt2);
}
for (int i = low; i < high; i++)
{
int index = (m_pNum[i] < 10 ? 0 : 1);
QPoint pnt3 = QPoint(i * dMul + dWidth / 2 - 2 * index, dLen * dMul + 50 - m_pNum[i] * dMul - 5);
pen.setColor(Qt::red);
painter.setPen(pen);
painter.drawText(pnt3, QString::number(m_pNum[i]));
}
painter.end();
m_pNumQLabel->setPixmap(QPixmap::fromImage(*m_pSortImg));
m_pNumQLabel->setFixedSize(m_pSortImg->width(), m_pSortImg->height());
this->resize(m_pSortImg->width() * 2 + 100, m_pSortImg->height() + 50);
QApplication::processEvents();
QTime dieTime = QTime::currentTime().addMSecs(m_dTime);
while (QTime::currentTime() < dieTime)
{
QApplication::processEvents();
}
}
除了要画出整个数组之外,还要把排序过程中哪些变化的item标注出来,所以要对变化的元素单独画一遍:
void QtSort::drawArray2QImg(int index, Qt::GlobalColor color1, Qt::GlobalColor color2)
{
if (NULL == m_pNum || NULL == m_pSortImg)
{
return;
}
//m_pSortImg->fill(Qt::black);
QPainter painter(this);
QPen pen;
pen.setColor(color1);
pen.setWidth(dWidth);
QFont font;
font.setPointSize(10);
font.setBold(true);
painter.begin(m_pSortImg);
painter.setPen(pen);
painter.setFont(font);
pen.setColor(color1);
painter.setPen(pen);
QPoint pnt1 = QPoint(index * dMul + dWidth / 2 + 4, dLen * dMul + 50);
QPoint pnt2 = QPoint(index * dMul + dWidth / 2 + 4, dLen * dMul + 50 - m_pNum[index] * dMul + 5);
painter.drawLine(pnt1, pnt2);
int dIndex = (m_pNum[index] < 10 ? 0 : 1);
QPoint pnt3 = QPoint(index * dMul + dWidth / 2 - 2 * dIndex, dLen * dMul + 50 - m_pNum[index] * dMul - 5);
pen.setColor(color2);
painter.setPen(pen);
painter.drawText(pnt3, QString::number(m_pNum[index]));
painter.end();
m_pNumQLabel->setPixmap(QPixmap::fromImage(*m_pSortImg));
m_pNumQLabel->setFixedSize(m_pSortImg->width(), m_pSortImg->height());
this->resize(m_pSortImg->width() * 2 + 100, m_pSortImg->height() + 50);
QApplication::processEvents();
QTime dieTime = QTime::currentTime().addMSecs(m_dTime);
while (QTime::currentTime() < dieTime)
{
QApplication::processEvents();
}
}
由于是今天刚写的,代码上还需要优化的,不过基本的效果都出来了,倒也不错哈。现在展示下结果吧:
冒泡:
选择:
插入:
希尔:
归并:
快速:
只是简单的展示下而已,不过还是挺好玩的。
山光物态弄春辉,
莫为轻阴便拟归。
纵使晴明无雨色,
入云深处亦沾衣。
上善若水,为而不争。