Qt实现 动态化遍历二叉树(前中后层次遍历)
Posted kekexxr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt实现 动态化遍历二叉树(前中后层次遍历)相关的知识,希望对你有一定的参考价值。
binarytree.h 头文件
1 #ifndef LINKEDBINARYTREE_H 2 #define LINKEDBINARYTREE_H 3 #include<c++/algorithm> 4 #include<c++/cstdio> 5 #include<string> 6 #include<c++/string> 7 #include<c++/vector> 8 #include<vector> 9 #include<iostream> 10 #include"cirqueue.h" 11 12 using namespace std; 13 struct BinTreeNode 14 { 15 char data; 16 BinTreeNode*leftChild, *rightChild; 17 BinTreeNode() { leftChild = NULL; rightChild = NULL; } 18 BinTreeNode(char x, BinTreeNode*l = NULL, BinTreeNode *r = NULL) 19 { 20 data = x; 21 leftChild = l; 22 rightChild = r; 23 } 24 }; 25 class linkedBinaryTree 26 { 27 28 29 private: 30 BinTreeNode * root; 31 // void PreOrder(BinTreeNode * bt); // 前序遍历函数调用 32 // void InOrder(BinTreeNode * bt); // 中序遍历函数调用 33 // void PostOrder(BinTreeNode * bt); // 后序遍历函数调用 34 public: 35 //记录前中后 层次遍历以后的数据 36 vector<char> listPre; 37 vector<char> listMid; 38 vector<char> listLast; 39 vector<char> listLevel; 40 41 42 linkedBinaryTree() {} 43 BinTreeNode* Rebuild(vector<char>pre, vector<char>mid); 44 45 void set(vector<char>pre, vector<char>mid) 46 { 47 root = this->Rebuild(pre, mid); 48 } 49 BinTreeNode*getRoot(){return root;} 50 int getHeight(){int num=this->getHeight(root);return num;} 51 int getHeight(BinTreeNode*subTree) 52 { 53 if (subTree == NULL)return 0; 54 int i = getHeight(subTree->leftChild); 55 int j = getHeight(subTree->rightChild); 56 return (i < j) ? j + 1 : i + 1; 57 } 58 void PreOrder(BinTreeNode * bt) ; // 递归前序遍历二叉树 59 void InOrder(BinTreeNode * bt) ; // 递归中序遍历二叉树 60 void PostOrder(BinTreeNode * bt); // 递归后序遍历二叉树 61 void LeverOrder(); // 层序遍历二叉树 62 63 64 65 }; 66 67 68 inline void linkedBinaryTree::LeverOrder() 69 { 70 Queue<BinTreeNode *> Q; // 定义一个队列 71 Q.front=Q.rear=-1; // 顺序队列 72 if (root == NULL) 73 return; 74 Q.queue[++Q.rear]=root;// 根指针入队 75 while (Q.front != Q.rear) 76 { 77 BinTreeNode * q = Q.queue[++Q.front]; // 出队 78 cout<<q->data; 79 listLevel.push_back(q->data); 80 if (q->leftChild != NULL) 81 Q.queue[++Q.rear] = q->leftChild; // 左孩子入队 82 if (q->rightChild != NULL) 83 Q.queue[++Q.rear] = q->rightChild; // 右孩子入队 84 } 85 86 } 87 88 89 90 91 inline void linkedBinaryTree::PreOrder(BinTreeNode * bt) 92 { 93 if (bt == NULL)// 递归调用的结束条件 94 return; 95 cout << bt->data;// 访问根节点bt的数据域 96 listPre.push_back(bt->data); 97 PreOrder(bt->leftChild);// 前序递归遍历bt的左子树 98 PreOrder(bt->rightChild);// 前序递归遍历bt的右子树 99 } 100 101 102 103 inline void linkedBinaryTree::InOrder(BinTreeNode * bt) 104 { 105 if (bt == NULL) 106 return; 107 InOrder(bt->leftChild); 108 cout << bt->data; 109 listMid.push_back(bt->data); 110 InOrder(bt->rightChild); 111 } 112 113 114 inline void linkedBinaryTree::PostOrder(BinTreeNode * bt) 115 { 116 if (bt == NULL) 117 return; 118 PostOrder(bt->leftChild); 119 PostOrder(bt->rightChild); 120 cout << bt->data; 121 listLast.push_back(bt->data); 122 } 123 124 125 126 #endif // LINKEDBINARYTREE_H
binarytree.cpp文件
1 #include<c++/vector> 2 #include"binarytree.h" 3 #include<c++/vector> 4 #include<c++/string> 5 #include<c++/algorithm> 6 using namespace std; 7 BinTreeNode* linkedBinaryTree::Rebuild(vector<char> pre, vector<char> mid) 8 { 9 int nodeSize = mid.size(); 10 if (nodeSize == 0) 11 return NULL; 12 vector<char> leftPre, leftMid, rightPre, rightMid; 13 BinTreeNode* Root = new BinTreeNode(pre[0]); 14 int rootPos = 0; 15 for (int i = 0; i < nodeSize; i++) 16 { 17 if (mid[i] == pre[0]) 18 { 19 rootPos = i; 20 break; 21 } 22 } 23 for (int i = 0; i < nodeSize; i++) 24 { 25 if (i < rootPos) 26 { 27 28 leftMid.push_back(mid[i]); 29 30 leftPre.push_back(pre[i + 1]); 31 } 32 else if (i > rootPos) 33 { 34 35 rightMid.push_back(mid[i]); 36 rightPre.push_back(pre[i]); 37 } 38 } 39 Root->leftChild = Rebuild(leftPre, leftMid); 40 Root->rightChild = Rebuild(rightPre, rightMid); 41 return Root; 42 }
cirqueue.h头文件
1 #ifndef CIRQUEUE_H 2 #define CIRQUEUE_H 3 #pragma once 4 #include <iostream> 5 template<class T> 6 class Queue { 7 // FIFO 对象 8 public : 9 Queue(int MaxQueueSize = 10); 10 ~Queue() {delete [] queue;} 11 bool IsEmpty() const {return front == rear;} 12 bool IsFull() const {return ( 13 ((rear + 1) % MaxSize == front) ? 1 : 0);} 14 T First() const; //返回队首元素 15 T Last() const; // 返回队尾元素 16 Queue<T>& Add(const T& x); 17 Queue<T>& Delete(T& x); 18 int front; //与第一个元素在反时针方向上相差一个位置 19 int rear; // 指向最后一个元素 20 int MaxSize; // 队列数组的大小 21 T *queue; // 数组 22 } ; 23 24 template<class T> 25 Queue<T>::Queue(int MaxQueueSize) 26 {// 创建一个容量为 M a x Q u e u e S i z e的空队列 27 MaxSize = MaxQueueSize + 1; 28 queue = new T[MaxSize]; 29 front = rear = 0; 30 } 31 template<class T> 32 T Queue<T>::First() const 33 {// 返回队列的第一个元素 34 // 如果队列为空,则引发异常O u t O f B o u n d s 35 if (IsEmpty()) throw "OutOfBounds()"; 36 return queue[(front + 1) % MaxSize]; 37 } 38 template<class T> 39 T Queue<T>::Last() const 40 {// 返回队列的最后一个元素 41 // 如果队列为空,则引发异常O u t O f B o u n d s 42 if (IsEmpty()) throw "OutOfBounds()"; 43 return queue[rear]; 44 } 45 template<class T> 46 Queue<T>& Queue<T>::Add(const T& x) 47 {// 把 x 添加到队列的尾部 48 // 如果队列满,则引发异常 NoMem 49 if (IsFull()) throw "NoMem()"; 50 rear = (rear + 1) % MaxSize; 51 queue[rear] = x; 52 return *this; 53 } 54 template<class T> 55 Queue<T>& Queue<T>::Delete(T& x) 56 {// 删除第一个元素,并将其送入 x 57 // 如果队列为空,则引发异常 O u t O f B o u n d s 58 if (IsEmpty()) throw "OutOfBounds()"; 59 front = (front + 1) % MaxSize; 60 x = queue[front]; 61 return *this; 62 } 63 64 65 #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文件
1 #include"paint.h" 2 #include <QPainter> 3 #include<stack> 4 #include<cstdio> 5 #include<QStack> 6 #include<QStack> 7 #include"binarytree.h" 8 #include<QPoint> 9 #include<cmath> 10 #include<c++/vector> 11 #include<QTimer> 12 #include<string> 13 14 15 //按照顺序保存生成的树 16 vector<int>xslot;vector<int>yslot; 17 vector<char>xyData; 18 static int numberPre=0;//用来记录执行次数 19 static int numberMid=0; 20 static int numberLast=0; 21 static int numberLevel=0; 22 //extern vector<char> listPre; 23 24 25 Paint::Paint(QWidget *parent) : QWidget(parent) 26 { //设置计时器 27 QTimer *timer = new QTimer(this); 28 timer->start(1000);//一秒钟 29 connect(timer,SIGNAL(timeout()),this,SLOT(update())); 30 // if(number>xyData.size()) 31 // { 32 // number=0; 33 // timer->stop(); 34 35 // } 36 37 38 resize(600, 400); 39 // myTree = new linkedBinaryTree(); 40 } 41 42 bool Paint::setInput(QString input1, QString input2,linkedBinaryTree *myTree) 43 { 44 std::string s1 = input1.toStdString(); 45 std::string s2 = input2.toStdString(); 46 vector<char>v1; 47 vector<char>v2; 48 for(int i=0;i<s1.size();i++){v1.push_back(s1[i]);}; 49 for(int i=0;i<s2.size();i++){v2.push_back(s2[i]);}; 50 myTree->set(v1,v2); 51 myTreepaint=myTree; 52 return true; 53 } 54 55 void Paint::draw(BinTreeNode *node, int x, int y, int angle, bool isLeft, int depth, QPainter *p) 56 { xslot.push_back(x);yslot.push_back(y); 57 xyData.push_back(node->data); 58 59 60 61 int leftAngle, rightAngle; 62 int dx,dy,nx,ny; 63 if (node==NULL) 64 return; 65 p->save(); 66 p->setBrush(QColor(255, 160, 90)); 67 p->drawEllipse(x-10,y-20,20,20); 68 p->restore(); 69 p->drawText(x,y,QChar(node->data)); 70 if (node->leftChild!=NULL) 71 { 72 if (depth<2) 73 { 74 leftAngle = angle + rand()%15; 75 } else 76 { 77 if (!isLeft) { 78 leftAngle = angle + rand()%5 + 10; 79 } else { 80 leftAngle = rand()%45; 81 } 82 } 83 int lenEdge = rootLengt-depth*35; 84 dx = -cos(leftAngle*PI/180)*lenEdge; 85 dy = sin(leftAngle*PI/180)*lenEdge; 86 nx = x+dx; 87 ny = y+dy; 88 p->drawLine(x,y,nx,ny); 89 draw(node->leftChild,nx,ny,leftAngle,true,depth+1,p); 90 } 91 if (node->rightChild!=NULL) 92 { 93 if (depth<2) 94 { 95 rightAngle = angle + rand()%15; 96 } else 97 { 98 if (isLeft) 99 { 100 rightAngle = angle + rand()%5 + 10; 101 } 102 else 103 { 104 rightAngle = rand()%45; 105 } 106 } 107 int lenEdge = rootLengt-depth*15; 108 dx = cos(rightAngle*PI/180)*lenEdge; 109 dy = sin(rightAngle*PI/180)*lenEdge; 110 nx = x+dx; 111 ny = y+dy; 112 p->drawLine(x,y,nx,ny); 113 draw(node->rightChild,nx,ny,rightAngle,false,depth+1,p); 114 115 } 116 if (node->leftChild==NULL && node->rightChild==NULL) {return ; } 117 118 } 119 120 void Paint::draw_preOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){ 121 122 123 int pos; 124 //绘制画图函数 125 painter->save(); 126 painter->setBrush(QColor(100,0,0,100)); 127 for(int i=0;i<data.size();i++){ 128 if(data[numberPre]==xyData[i]){ 129 pos=i; 130 } 131 } 132 int a=x[pos];int b=y[pos]; 133 134 painter->drawEllipse(a-10,b-10,20,20); 135 painter->restore(); 136 painter->drawText(a,b,data[numberPre]+""); 137 numberPre++; 138 } 139 140 void Paint::draw_midOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){ 141 int pos; 142 //绘制画图函数 143 painter->save(); 144 painter->setBrush(QColor(0,100,0,100)); 145 for(int i=0;i<data.size();i++){ 146 if(data[numberMid]==xyData[i]){ 147 pos=i; 148 } 149 } 150 int a=x[pos];int b=y[pos]; 151 152 painter->drawEllipse(a-10,b-10,20,20); 153 painter->restore(); 154 painter->drawText(a,b,data[numberMid]+""); 155 numberMid++; 156 } 157 158 void Paint:: draw_lastOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){ 159 int pos; 160 //绘制画图函数 161 painter->save(); 162 painter->setBrush(QColor(100,0,0,100)); 163 for(int i=0;i<data.size();i++){ 164 if(data[numberLast]==xyData[i]){ 165 pos=i; 166 } 167 } 168 int a=x[pos];int b=y[pos]; 169 170 painter->drawEllipse(a-10,b-10,20,20); 171 painter->restore(); 172 painter->drawText(a,b,data[numberLast]+""); 173 numberLast++; 174 } 175 void Paint::draw_levelOrder(vector<int>x,vector<int>y,vector<char>data,QPainter *painter){ 176 int pos; 177 //绘制画图函数 178 painter->save(); 179 painter->setBrush(QColor(100,0,0,100)); 180 for(int i=0;i<data.size();i++){ 181 if(data[numberLevel]==xyData[i]){ 182 pos=i; 183 } 184 } 185 int a=x[pos];int b=y[pos]; 186 187 painter->drawEllipse(a-10,b-10,20,20); 188 painter->restore(); 189 painter->drawText(a,b,data[numberLevel]+""); 190 numberLevel++; 191 } 192 void Paint::paintEvent(QPaintEvent *e) 193 { 194 QPainter p(this); 195 draw(myTreepaint->getRoot(), width()/4, height()/8, 10, true, 0, &p); 196 //????????? 197 //?????????? 198 //????????? 199 //???????????传不进来参数嘤嘤嘤! 200 if(false){//前序 201 vector<char> pre={‘A‘,‘B‘,‘C‘,‘E‘,‘H‘,‘F‘,‘I‘,‘J‘,‘D‘,‘G‘,‘K‘}; 202 draw_preOrder(xslot,yslot,pre,&p); 203 } 204 if(false){//中序 205 206 vector<char> mid={‘A‘, ‘H‘, ‘E‘, ‘C‘, ‘I‘, ‘F‘, ‘J‘ ,‘B‘, ‘D‘, ‘K‘, ‘G‘}; 207 draw_midOrder(xslot,yslot,mid,&p); 208 } 209 if(false){//后序 210 vector<char> last={‘H‘,‘E‘,‘I‘,‘J‘,‘F‘,‘C‘,‘K‘,‘G‘,‘D‘,‘B‘,‘A‘}; 211 draw_lastOrder(xslot,yslot,last,&p); 212 } 213 //层次 214 if(false){ 215 vector<char> level={‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘,‘G‘,‘H‘,‘I‘,‘J‘,‘K‘}; 216 draw_preOrder(xslot,yslot,level,&p);} 217 218 219 }
widget.h
1 #ifndef WIDGET_H 2 #define WIDGET_H 3 4 #include <QWidget> 5 #include"binarytree.h" 6 namespace Ui { 7 class Widget; 8 } 9 10 class Widget : public QWidget 11 { 12 Q_OBJECT 13 14 public: 15 explicit Widget(QWidget *parent = 0); 16 ~Widget(); 17 linkedBinaryTree* myTree; 18 public slots: 19 void on_btnCreat_clicked(); 20 void on_clear_clicked(); 21 private slots: 22 void on_preButton_clicked(); 23 24 void on_midButton_clicked(); 25 26 void on_lastButton_clicked(); 27 28 void on_levelButton_clicked(); 29 30 private: 31 Ui::Widget *ui; 32 }; 33 34 #endif // WIDGET_H
widget.cpp文件
1 #include "widget.h" 2 #include"paint.h" 3 #include"binarytree.h" 4 #include "ui_widget.h" 5 #include<c++/vector> 6 #include<QMessageBox> 7 #include <iterator> 8 #include <algorithm> 9 #include<QTimer> 10 #include<QTime> 11 12 Widget::Widget(QWidget *parent) : 13 QWidget(parent), 14 ui(new Ui::Widget) 15 { 16 ui->setupUi(this); 17 connect(ui->Create,SIGNAL(clicked(bool)),this,SLOT(on_btnCreat_clicked())); 18 connect(ui->clear,SIGNAL(clicked(bool)),this,SLOT(on_clear_clicked())); 19 connect(ui->preButton,SIGNAL(clicked(bool)),this,SLOT(on_preButton_clicked())); 20 connect(ui->midButton,SIGNAL(clicked(bool)),this,SLOT(on_midButton_clicked())); 21 connect(ui->lastButton,SIGNAL(clicked(bool)),this,SLOT(on_lastButton_clicked())); 22 connect(ui->levelButton,SIGNAL(clicked(bool)),this,SLOT(on_levelButton_clicked())); 23 } 24 25 Widget::~Widget() 26 { 27 delete ui; 28 } 29 void Widget::on_btnCreat_clicked() 30 { myTree = new linkedBinaryTree(); 31 QString input1 = ui->lEdInput1->text(); 32 QString input2 = ui->lEdInput2->text(); 33 Paint *p = new Paint(); 34 p->setInput(input1,input2,myTree); 35 p->show(); 36 } 37 void Widget::on_clear_clicked() 38 { 39 ui->lEdInput2->clear(); 40 ui->lEdInput1->clear(); 41 } 42 43 void Widget::on_preButton_clicked() 44 { myTree = new linkedBinaryTree(); 45 QString input1 = ui->lEdInput1->text(); 46 QString input2 = ui->lEdInput2->text(); 47 Paint *p = new Paint(); 48 p->setInput(input1,input2,myTree); 49 50 BinTreeNode *root=myTree->getRoot(); 51 myTree->PreOrder(root); 52 53 54 55 56 } 57 58 void Widget::on_midButton_clicked() 59 { 60 myTree = new linkedBinaryTree(); 61 QString input1 = ui->lEdInput1->text(); 62 QString input2 = ui->lEdInput2->text(); 63 Paint *p = new Paint(); 64 p->setInput(input1,input2,myTree); 65 66 BinTreeNode *root=myTree->getRoot(); 67 myTree->InOrder(root); 68 69 } 70 71 void Widget::on_lastButton_clicked() 72 { 73 myTree = new linkedBinaryTree(); 74 QString input1 = ui->lEdInput1->text(); 75 QString input2 = ui->lEdInput2->text(); 76 Paint *p = new Paint(); 77 p->setInput(input1,input2,myTree); 78 79 BinTreeNode *root=myTree->getRoot(); 80 myTree->PostOrder(root); 81 } 82 83 void Widget::on_levelButton_clicked() 84 { 85 myTree = new linkedBinaryTree(); 86 QString input1 = ui->lEdInput1->text(); 87 QString input2 = ui->lEdInput2->text(); 88 Paint *p = new Paint(); 89 p->setInput(input1,input2,myTree); 90 91 92 myTree->LeverOrder(); 93 94 }
main.cpp
1 #include "widget.h" 2 #include <QApplication> 3 4 int main(int argc, char *argv[]) 5 { 6 QApplication a(argc, argv); 7 Widget w; 8 w.show(); 9 return a.exec(); 10 }
以上是关于Qt实现 动态化遍历二叉树(前中后层次遍历)的主要内容,如果未能解决你的问题,请参考以下文章
二叉树遍历算法——包含递归前中后序和层次,非递归前中后序和层次遍历共八种