Qt实现 动态化遍历二叉树(前中后层次遍历)
binarytree.h 头文件
#ifndef LINKEDBINARYTREE_H
#define LINKEDBINARYTREE_H
#include<c++/algorithm>
#include<c++/cstdio>
#include<string>
#include<c++/string>
#include<c++/vector>
#include<vector>
#include<iostream>
#include"cirqueue.h" using namespace std;
struct BinTreeNode
{
char data;
BinTreeNode*leftChild, *rightChild;
BinTreeNode() { leftChild = NULL; rightChild = NULL; }
BinTreeNode(char x, BinTreeNode*l = NULL, BinTreeNode *r = NULL)
{
data = x;
leftChild = l;
rightChild = r;
}
};
class linkedBinaryTree
{ private:
BinTreeNode * root;
// void PreOrder(BinTreeNode * bt); // 前序遍历函数调用
// void InOrder(BinTreeNode * bt); // 中序遍历函数调用
// void PostOrder(BinTreeNode * bt); // 后序遍历函数调用
public:
//记录前中后 层次遍历以后的数据
vector<char> listPre;
vector<char> listMid;
vector<char> listLast;
vector<char> listLevel; linkedBinaryTree() {}
BinTreeNode* Rebuild(vector<char>pre, vector<char>mid); void set(vector<char>pre, vector<char>mid)
{
root = this->Rebuild(pre, mid);
}
BinTreeNode*getRoot(){return root;}
int getHeight(){int num=this->getHeight(root);return num;}
int getHeight(BinTreeNode*subTree)
{
if (subTree == NULL)return ;
int i = getHeight(subTree->leftChild);
int j = getHeight(subTree->rightChild);
return (i < j) ? j + : i + ;
}
void PreOrder(BinTreeNode * bt) ; // 递归前序遍历二叉树
void InOrder(BinTreeNode * bt) ; // 递归中序遍历二叉树
void PostOrder(BinTreeNode * bt); // 递归后序遍历二叉树
void LeverOrder(); // 层序遍历二叉树 }; inline void linkedBinaryTree::LeverOrder()
{
Queue<BinTreeNode *> Q; // 定义一个队列
Q.front=Q.rear=-; // 顺序队列
if (root == NULL)
return;
Q.queue[++Q.rear]=root;// 根指针入队
while (Q.front != Q.rear)
{
BinTreeNode * q = Q.queue[++Q.front]; // 出队
cout<<q->data;
listLevel.push_back(q->data);
if (q->leftChild != NULL)
Q.queue[++Q.rear] = q->leftChild; // 左孩子入队
if (q->rightChild != NULL)
Q.queue[++Q.rear] = q->rightChild; // 右孩子入队
} } inline void linkedBinaryTree::PreOrder(BinTreeNode * bt)
{
if (bt == NULL)// 递归调用的结束条件
return;
cout << bt->data;// 访问根节点bt的数据域
listPre.push_back(bt->data);
PreOrder(bt->leftChild);// 前序递归遍历bt的左子树
PreOrder(bt->rightChild);// 前序递归遍历bt的右子树
} inline void linkedBinaryTree::InOrder(BinTreeNode * bt)
{
if (bt == NULL)
return;
InOrder(bt->leftChild);
cout << bt->data;
listMid.push_back(bt->data);
InOrder(bt->rightChild);
} inline void linkedBinaryTree::PostOrder(BinTreeNode * bt)
{
if (bt == NULL)
return;
PostOrder(bt->leftChild);
PostOrder(bt->rightChild);
cout << bt->data;
listLast.push_back(bt->data);
} #endif // LINKEDBINARYTREE_H
binarytree.cpp文件
#include<c++/vector>
#include"binarytree.h"
#include<c++/vector>
#include<c++/string>
#include<c++/algorithm>
using namespace std;
BinTreeNode* linkedBinaryTree::Rebuild(vector<char> pre, vector<char> mid)
{
int nodeSize = mid.size();
if (nodeSize == )
return NULL;
vector<char> leftPre, leftMid, rightPre, rightMid;
BinTreeNode* Root = new BinTreeNode(pre[]);
int rootPos = ;
for (int i = ; i < nodeSize; i++)
{
if (mid[i] == pre[])
{
rootPos = i;
break;
}
}
for (int i = ; i < nodeSize; i++)
{
if (i < rootPos)
{ leftMid.push_back(mid[i]); leftPre.push_back(pre[i + ]);
}
else if (i > rootPos)
{ rightMid.push_back(mid[i]);
rightPre.push_back(pre[i]);
}
}
Root->leftChild = Rebuild(leftPre, leftMid);
Root->rightChild = Rebuild(rightPre, rightMid);
return Root;
}
cirqueue.h头文件
#ifndef CIRQUEUE_H
#define CIRQUEUE_H
#pragma once
#include <iostream>
template<class T>
class Queue {
// FIFO 对象
public :
Queue(int MaxQueueSize = );
~Queue() {delete [] queue;}
bool IsEmpty() const {return front == rear;}
bool IsFull() const {return (
((rear + ) % MaxSize == front) ? : );}
T First() const; //返回队首元素
T Last() const; // 返回队尾元素
Queue<T>& Add(const T& x);
Queue<T>& Delete(T& x);
int front; //与第一个元素在反时针方向上相差一个位置
int rear; // 指向最后一个元素
int MaxSize; // 队列数组的大小
T *queue; // 数组
} ; template<class T>
Queue<T>::Queue(int MaxQueueSize)
{// 创建一个容量为 M a x Q u e u e S i z e的空队列
MaxSize = MaxQueueSize + ;
queue = new T[MaxSize];
front = rear = ;
}
template<class T>
T Queue<T>::First() const
{// 返回队列的第一个元素
// 如果队列为空,则引发异常O u t O f B o u n d s
if (IsEmpty()) throw "OutOfBounds()";
return queue[(front + ) % MaxSize];
}
template<class T>
T Queue<T>::Last() const
{// 返回队列的最后一个元素
// 如果队列为空,则引发异常O u t O f B o u n d s
if (IsEmpty()) throw "OutOfBounds()";
return queue[rear];
}
template<class T>
Queue<T>& Queue<T>::Add(const T& x)
{// 把 x 添加到队列的尾部
// 如果队列满,则引发异常 NoMem
if (IsFull()) throw "NoMem()";
rear = (rear + ) % MaxSize;
queue[rear] = x;
return *this;
}
template<class T>
Queue<T>& Queue<T>::Delete(T& x)
{// 删除第一个元素,并将其送入 x
// 如果队列为空,则引发异常 O u t O f B o u n d s
if (IsEmpty()) throw "OutOfBounds()";
front = (front + ) % MaxSize;
x = queue[front];
return *this;
} #endif // CIRQUEUE_H
paint.h头文件
#ifndef PAINT_H
#define PAINT_H
#include"binarytree.h"
#include <QWidget>
class Paint : public QWidget
{
Q_OBJECT
public:
explicit Paint(QWidget *parent = 0);
bool setInput(QString input1, QString input2,linkedBinaryTree *myTree);
void paintEvent(QPaintEvent *);
void draw(BinTreeNode *node, int x, int y, int angle, bool isLeft, int depth, QPainter *p);
BinTreeNode* test();
//绘制前中后 层次遍历的函数
void draw_preOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter);
void draw_midOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter);
void draw_lastOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter);
void draw_levelOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter);
private:
linkedBinaryTree* myTreepaint;
const int rootLengt=160;
const double PI=3.1415926;
};
#endif // PAINT_H
paint.cpp文件
#include"paint.h"
#include <QPainter>
#include<stack>
#include<cstdio>
#include<QStack>
#include<QStack>
#include"binarytree.h"
#include<QPoint>
#include<cmath>
#include<c++/vector>
#include<QTimer>
#include<string> //按照顺序保存生成的树
vector<int>xslot;vector<int>yslot;
vector<char>xyData;
static int numberPre=;//用来记录执行次数
static int numberMid=;
static int numberLast=;
static int numberLevel=;
//extern vector<char> listPre; Paint::Paint(QWidget *parent) : QWidget(parent)
{ //设置计时器
QTimer *timer = new QTimer(this);
timer->start();//一秒钟
connect(timer,SIGNAL(timeout()),this,SLOT(update()));
// if(number>xyData.size())
// {
// number=0;
// timer->stop(); // } resize(, );
// myTree = new linkedBinaryTree();
} bool Paint::setInput(QString input1, QString input2,linkedBinaryTree *myTree)
{
std::string s1 = input1.toStdString();
std::string s2 = input2.toStdString();
vector<char>v1;
vector<char>v2;
for(int i=;i<s1.size();i++){v1.push_back(s1[i]);};
for(int i=;i<s2.size();i++){v2.push_back(s2[i]);};
myTree->set(v1,v2);
myTreepaint=myTree;
return true;
} void Paint::draw(BinTreeNode *node, int x, int y, int angle, bool isLeft, int depth, QPainter *p)
{ xslot.push_back(x);yslot.push_back(y);
xyData.push_back(node->data); int leftAngle, rightAngle;
int dx,dy,nx,ny;
if (node==NULL)
return;
p->save();
p->setBrush(QColor(, , ));
p->drawEllipse(x-,y-,,);
p->restore();
p->drawText(x,y,QChar(node->data));
if (node->leftChild!=NULL)
{
if (depth<)
{
leftAngle = angle + rand()%;
} else
{
if (!isLeft) {
leftAngle = angle + rand()% + ;
} else {
leftAngle = rand()%;
}
}
int lenEdge = rootLengt-depth*;
dx = -cos(leftAngle*PI/)*lenEdge;
dy = sin(leftAngle*PI/)*lenEdge;
nx = x+dx;
ny = y+dy;
p->drawLine(x,y,nx,ny);
draw(node->leftChild,nx,ny,leftAngle,true,depth+,p);
}
if (node->rightChild!=NULL)
{
if (depth<)
{
rightAngle = angle + rand()%;
} else
{
if (isLeft)
{
rightAngle = angle + rand()% + ;
}
else
{
rightAngle = rand()%;
}
}
int lenEdge = rootLengt-depth*;
dx = cos(rightAngle*PI/)*lenEdge;
dy = sin(rightAngle*PI/)*lenEdge;
nx = x+dx;
ny = y+dy;
p->drawLine(x,y,nx,ny);
draw(node->rightChild,nx,ny,rightAngle,false,depth+,p); }
if (node->leftChild==NULL && node->rightChild==NULL) {return ; } } void Paint::draw_preOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){ int pos;
//绘制画图函数
painter->save();
painter->setBrush(QColor(,,,));
for(int i=;i<data.size();i++){
if(data[numberPre]==xyData[i]){
pos=i;
}
}
int a=x[pos];int b=y[pos]; painter->drawEllipse(a-,b-,,);
painter->restore();
painter->drawText(a,b,data[numberPre]+"");
numberPre++;
} void Paint::draw_midOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){
int pos;
//绘制画图函数
painter->save();
painter->setBrush(QColor(,,,));
for(int i=;i<data.size();i++){
if(data[numberMid]==xyData[i]){
pos=i;
}
}
int a=x[pos];int b=y[pos]; painter->drawEllipse(a-,b-,,);
painter->restore();
painter->drawText(a,b,data[numberMid]+"");
numberMid++;
} void Paint:: draw_lastOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){
int pos;
//绘制画图函数
painter->save();
painter->setBrush(QColor(,,,));
for(int i=;i<data.size();i++){
if(data[numberLast]==xyData[i]){
pos=i;
}
}
int a=x[pos];int b=y[pos]; painter->drawEllipse(a-,b-,,);
painter->restore();
painter->drawText(a,b,data[numberLast]+"");
numberLast++;
}
void Paint::draw_levelOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){
int pos;
//绘制画图函数
painter->save();
painter->setBrush(QColor(,,,));
for(int i=;i<data.size();i++){
if(data[numberLevel]==xyData[i]){
pos=i;
}
}
int a=x[pos];int b=y[pos]; painter->drawEllipse(a-,b-,,);
painter->restore();
painter->drawText(a,b,data[numberLevel]+"");
numberLevel++;
}
void Paint::paintEvent(QPaintEvent *e)
{
QPainter p(this);
draw(myTreepaint->getRoot(), width()/, height()/, , true, , &p);
//?????????
//??????????
//?????????
//???????????传不进来参数嘤嘤嘤!
if(false){//前序
vector<char> pre={'A','B','C','E','H','F','I','J','D','G','K'};
draw_preOrder(xslot,yslot,pre,&p);
}
if(false){//中序 vector<char> mid={'A', 'H', 'E', 'C', 'I', 'F', 'J' ,'B', 'D', 'K', 'G'};
draw_midOrder(xslot,yslot,mid,&p);
}
if(false){//后序
vector<char> last={'H','E','I','J','F','C','K','G','D','B','A'};
draw_lastOrder(xslot,yslot,last,&p);
}
//层次
if(false){
vector<char> level={'A','B','C','D','E','F','G','H','I','J','K'};
draw_preOrder(xslot,yslot,level,&p);} }
widget.h
#ifndef WIDGET_H
#define WIDGET_H #include <QWidget>
#include"binarytree.h"
namespace Ui {
class Widget;
} class Widget : public QWidget
{
Q_OBJECT public:
explicit Widget(QWidget *parent = );
~Widget();
linkedBinaryTree* myTree;
public slots:
void on_btnCreat_clicked();
void on_clear_clicked();
private slots:
void on_preButton_clicked(); void on_midButton_clicked(); void on_lastButton_clicked(); void on_levelButton_clicked(); private:
Ui::Widget *ui;
}; #endif // WIDGET_H
widget.cpp文件
#include "widget.h"
#include"paint.h"
#include"binarytree.h"
#include "ui_widget.h"
#include<c++/vector>
#include<QMessageBox>
#include <iterator>
#include <algorithm>
#include<QTimer>
#include<QTime> Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->Create,SIGNAL(clicked(bool)),this,SLOT(on_btnCreat_clicked()));
connect(ui->clear,SIGNAL(clicked(bool)),this,SLOT(on_clear_clicked()));
connect(ui->preButton,SIGNAL(clicked(bool)),this,SLOT(on_preButton_clicked()));
connect(ui->midButton,SIGNAL(clicked(bool)),this,SLOT(on_midButton_clicked()));
connect(ui->lastButton,SIGNAL(clicked(bool)),this,SLOT(on_lastButton_clicked()));
connect(ui->levelButton,SIGNAL(clicked(bool)),this,SLOT(on_levelButton_clicked()));
} Widget::~Widget()
{
delete ui;
}
void Widget::on_btnCreat_clicked()
{ myTree = new linkedBinaryTree();
QString input1 = ui->lEdInput1->text();
QString input2 = ui->lEdInput2->text();
Paint *p = new Paint();
p->setInput(input1,input2,myTree);
p->show();
}
void Widget::on_clear_clicked()
{
ui->lEdInput2->clear();
ui->lEdInput1->clear();
} void Widget::on_preButton_clicked()
{ myTree = new linkedBinaryTree();
QString input1 = ui->lEdInput1->text();
QString input2 = ui->lEdInput2->text();
Paint *p = new Paint();
p->setInput(input1,input2,myTree); BinTreeNode *root=myTree->getRoot();
myTree->PreOrder(root); } void Widget::on_midButton_clicked()
{
myTree = new linkedBinaryTree();
QString input1 = ui->lEdInput1->text();
QString input2 = ui->lEdInput2->text();
Paint *p = new Paint();
p->setInput(input1,input2,myTree); BinTreeNode *root=myTree->getRoot();
myTree->InOrder(root); } void Widget::on_lastButton_clicked()
{
myTree = new linkedBinaryTree();
QString input1 = ui->lEdInput1->text();
QString input2 = ui->lEdInput2->text();
Paint *p = new Paint();
p->setInput(input1,input2,myTree); BinTreeNode *root=myTree->getRoot();
myTree->PostOrder(root);
} void Widget::on_levelButton_clicked()
{
myTree = new linkedBinaryTree();
QString input1 = ui->lEdInput1->text();
QString input2 = ui->lEdInput2->text();
Paint *p = new Paint();
p->setInput(input1,input2,myTree); myTree->LeverOrder(); }
main.cpp
#include "widget.h"
#include <QApplication> int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Qt实现 动态化遍历二叉树(前中后层次遍历)的更多相关文章
- 二叉树前中后/层次遍历的递归与非递归形式(c++)
/* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...
- C++二叉树前中后序遍历(递归&非递归)统一代码格式
统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理. 三种递归格式: 前序遍历: void PreOrder(TreeNode* root, vector<int>&pa ...
- [C++] 非递归实现前中后序遍历二叉树
目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...
- 【C++】二叉树的遍历(前中后)- 迭代法
力扣题目:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/ 今天自己琢磨了很久如何不用递归将二叉树的遍历写出来,于是乎写出 ...
- Binary Tree Traversal 二叉树的前中后序遍历
[抄题]:二叉树前序遍历 [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: 节点非空时往左移,否则新取一个点 再往右移. [输入量] ...
- POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)
链接:poj.org/problem?id=2255 本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html 题意: 分别给你一个二叉树的前序遍历序列和中序 ...
- C++实现对树的创建和前中后序遍历
#include<iostream>#include<stdio.h> using namespace std; class BitNode{ public: char dat ...
- 数据结构-C语言递归实现树的前中后序遍历
#include <stdio.h> #include <stdlib.h> typedef struct tree { int number ; struct tree *l ...
- 飘逸的python - 极简的二叉树前中后序通杀函数
对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...
随机推荐
- Tomcat启动后,访问页面报404错误解决方法
Tomcat正常启动后,出现如下情况 提供一个参考解决方法: 1.双击servers 2.把Server Locations设置为User Tomcat installation 保存后再次访问页面就 ...
- linux IPtable防火墙 禁止和开放端口
1.关闭所有的 INPUT FORWARD OUTPUT 只对某些端口开放.下面是命令实现: iptables -P INPUT DROPiptables -P FORWARD DROPiptable ...
- Java基本概述
1.java语言的特点 1.面向对象:基本概念(类,对象) 三大特征:封装.继承.多态 2.健壮性 3.跨平台:通过Java语言的编写的应用程序在不同的系统平台上都能可以进行运行. 2.什么是JDK. ...
- Java实训:实训一 ——长春职业技术学院 16级网络工程
Java实训:实训一 本文会解释一些设计思路. 想看具体过程,请转:https://www.cnblogs.com/lxwlxw/p/10114187.html 笑维的码云项目命名不太对,所以我来:h ...
- fastJson遇到的问题
概述 现在的代码开发中,json这种数据类型使用的是越来越多,因为它的存取速度都比较快,而且,使用起来非常的简单,今天工作的时候,我就遇到了一个关于json的生产问题,这个问题我之前确实还没有注意过, ...
- mybatis中<foreach>标签的使用
标签太多,记一下不是特别常用的标签~留着脑袋瓜不机灵的时候看! <foreach>标签 该标签的作用是遍历集合类型的条件 <select id="countByUserL ...
- Python处理数据库
使用数据库驱动连接数据库 (Connection对象) 打开游标(Cursor对象),并通过它执行SQL语句(execute方法) 提交操作(commit()) 关闭连接(close()) ORM将表 ...
- Context Encoder论文及代码解读
经过秋招和毕业论文的折磨,提交完论文終稿的那一刻总算觉得有多余的时间来搞自己的事情. 研究论文做的是图像修复相关,这里对基于深度学习的图像修复方面的论文和代码进行整理,也算是研究生方向有一个比较好的结 ...
- 如何将Excel转换成Markdown表格[转]
在这篇文章中,我将告诉你如何快速的将Excel转换为markdown表格,以及如何将Google Docs,Numbers,网页中的表格或其他类似Excel的程序数据转换为Markdown表格 你可能 ...
- 20175224 2018-2019-2 《Java程序设计》第五周学习总结
教材学习内容总结 第六章:接口与实现 接口:关键字interface来定义一个接口.分为接口声明,接口体. interface Printable { final int MAX=100; void ...