之前写了几个排序算法,然后看到别人将排序算法的过程可视化出来,所以就想尝试一下,然后就用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();
	}
}

由于是今天刚写的,代码上还需要优化的,不过基本的效果都出来了,倒也不错哈。现在展示下结果吧:

冒泡:

选择:

插入:

希尔:

归并:

快速:

只是简单的展示下而已,不过还是挺好玩的。

山光物态弄春辉,

莫为轻阴便拟归。 

纵使晴明无雨色,

入云深处亦沾衣。