• 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 }
  • 相关阅读:
    浏览器兼容模式下,上传文件问题
    计算机编程语言也是一种语言,认识的词汇越多越好
    localhost换成127.0.0.1和本机IP打不开本地项目了的问题
    mvc @html.action() 跨area调用controller 中的action
    windows server 2012 FTP连接报530 User 用户名 cannot log in home directory inaccessible的解决方法
    eCharts 数据转换json
    win10家庭版查看已连接wifi密码
    jequery动态创建form
    jsp 获取配置信息
    docker常用命令
  • 原文地址:https://www.cnblogs.com/kekexxr/p/10396474.html
Copyright © 2020-2023  润新知