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实现 动态化遍历二叉树(前中后层次遍历)的主要内容,如果未能解决你的问题,请参考以下文章

二叉树前中后层次遍历

二叉树遍历算法——包含递归前中后序和层次,非递归前中后序和层次遍历共八种

二叉树的前中后序遍历(java递归迭代分别实现)

递归非递归的二叉树遍历(递归前中后,非递归前中后,层次遍历,凹入打印法等)

二叉树前中后层次遍历的非递归法

二叉树的前中后序遍历简单的递归