关于二叉树见:《数据结构》学习记录(9):二叉树_友善啊,朋友的博客-CSDN博客
代码:
#ifndef FORM_H
#define FORM_H
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
protected:
void paintEvent(QPaintEvent *event)override;
private:
Ui::Form *ui;
class BTNode * root;
};
#endif // FORM_H
#include "form.h"
#include "ui_form.h"
#include <QStack>
#include <QDebug>
#include <iostream>
#include <QPainter>
#include <QPaintEvent>
#include <QRandomGenerator>
struct BTNode
{
QChar data;
BTNode * lchild{nullptr};
BTNode * rchild{nullptr};
};
//创建二叉树
void CreateBTNode(BTNode * & root,QString binaryTreeBracketNotationString)
{
root = nullptr;
enum class processTreeType//当前字符处理的类型
{
leftChildTree,
rightChildTree,
noChildTree
};
processTreeType nowNodeProcessTreeType{processTreeType::noChildTree};
BTNode * currentNode{nullptr};//当前创建的结点
QStack<BTNode*> stack;
for(const auto & element : qAsConst(binaryTreeBracketNotationString))
{
if(element == '(')//表示一棵左子树的开始,即将前面刚创建的结点作为双亲结点进栈
{
stack.push(currentNode);
nowNodeProcessTreeType = processTreeType::leftChildTree;
}
else if(element == ')')//表示一棵子树的结束
{
stack.pop();
}
else if(element == ',')//表示一棵右子树的开始
{
nowNodeProcessTreeType = processTreeType::rightChildTree;
}
else//字母,说明应该创建一个结点
{
currentNode = new BTNode;
currentNode->data = element;
if(!root)
root = currentNode;
else
{
switch (nowNodeProcessTreeType)
{
case processTreeType::leftChildTree:stack.top()->lchild = currentNode;break;
case processTreeType::rightChildTree:stack.top()->rchild = currentNode;break;
case processTreeType::noChildTree:;break;
}
}
}
}
}
//递归销毁二叉树
void DestroyBT(BTNode * & node)
{
if (!node)
return;
else
{
DestroyBT(node->lchild);
DestroyBT(node->rchild);
delete node;
node = nullptr;
}
}
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
QString binaryTreeBracketNotationString = "A(B(D(M(N,),G(W(,H),))),C(E,F(P,Z(,K(Y,)))))";
CreateBTNode(root,binaryTreeBracketNotationString);
}
Form::~Form()
{
DestroyBT(root);
delete ui;
}
QColor getRandomColor()
{
return QColor(QRandomGenerator::global()->bounded(255),
QRandomGenerator::global()->bounded(255),
QRandomGenerator::global()->bounded(255));
}
void drawNode(BTNode * node,QPainter & painter,QPoint dataCircleCenter)
{
static QPoint offsetPoint{20,20};
static QPen whitePen{Qt::white,5};
QRect rect = QRect(dataCircleCenter - offsetPoint,dataCircleCenter + offsetPoint);
if(node->lchild)
{
painter.drawLine(rect.center(),dataCircleCenter + QPoint(-60,60));
drawNode(node->lchild,painter,dataCircleCenter + QPoint(-60,60));
}
if(node->rchild)
{
painter.drawLine(rect.center(),dataCircleCenter + QPoint(60,60));
drawNode(node->rchild,painter,dataCircleCenter + QPoint(60,60));
}
painter.save();
painter.setBrush(getRandomColor());
painter.setPen(whitePen);
painter.drawEllipse(rect);
painter.drawText(rect,Qt::AlignCenter,node->data);
painter.restore();
}
void Form::paintEvent(QPaintEvent *event)
{
static QFont font{"微软雅黑",18};
QPainter painter(this);
painter.setFont(font);
painter.setRenderHint(QPainter::Antialiasing,true);
drawNode(root,painter,QPoint(event->rect().width()/2,40));
}
效果: