zoukankan      html  css  js  c++  java
  • 二叉树的实现_遍历_重构_树形显示

      1 //测试数据 
      2 //1 2 4 7 -1 -1 -1 5 -1 -1 3 -1 6 -1 -1
      3 //1 2 4 11 -1 22 -1 -1 -1 5 -1 -1 3 6 -1 -1 7 -1 -1
      4 
      5 
      6 #include <iostream>
      7 #include <cstring>
      8 using namespace std;
      9 
     10 template<typename T>
     11 struct BinaryNode
     12 { 
     13     T element;
     14     BinaryNode<T> *left;
     15     BinaryNode<T> *right;
     16 
     17     BinaryNode() : element(0), left(nullptr), right(nullptr) { } 
     18     BinaryNode(const T &theElement, BinaryNode *lt, BinaryNode *rt)
     19         : element(theElement), left(lt), right(rt) {}
     20     
     21 };
     22 
     23 
     24 template<typename T>
     25 class BinarySearchTree
     26 {
     27 public:
     28     BinarySearchTree() {
     29         root = nullptr;
     30     }
     31     BinarySearchTree(const BinarySearchTree& rhs) {  //复制构造函数
     32         root = clone(rhs.root);
     33     }
     34     ~BinarySearchTree();
     35     
     36     void RootCreate(const T& end); //创建根结点的以下结点 
     37     
     38     bool contains(const T& x) const;
     39 
     40     bool getNode(const T& e, const T&sub) {      
     41         if (getNode(e, root) != nullptr) {
     42             getNode(e, root)->element = sub;  //得到元素为e的结点 
     43             return true;
     44         }
     45         return false;        
     46     }
     47     
     48     //求父亲的值 
     49     T getParents(const T& e) const {
     50         return getParents(root, e);
     51     }
     52 
     53     bool isEmpty() const {
     54         if (root == nullptr)
     55             return true;   
     56         return false;     
     57     }                      
     58 
     59     void PreprintTree() const {
     60         PreprintTree(root);
     61     }
     62 
     63     void InprintTree() const {
     64         InprintTree(root);
     65     }
     66 
     67     void PostprintTree() const {
     68         PostprintTree(root);
     69     }
     70 
     71     void LevelprintTree() const {
     72         LevelprintTree(root);
     73     }
     74 
     75     void PreprintTree_N() const {
     76         PreprintTree_N(root);
     77     }
     78 
     79     void InprintTree_N() const {
     80         InprintTree_N(root);
     81     }
     82 
     83     void PostprintTree_N() const {
     84         PostprintTree_N(root);
     85     }
     86 
     87     void DisplayTreeShape(int level = 1) const {
     88         DisplayTreeShape(root, level);
     89     }
     90     
     91     void makeEmpty();
     92 
     93     void remove(const T &x);
     94 
     95     int Depth();
     96     int CountLeaf() {
     97         BinaryNode<T> *p = root;
     98         int count = 0;
     99         CountLeaf(p, count);
    100         return count;
    101     }
    102 
    103     const BinarySearchTree& operator = (const BinarySearchTree& rhs);
    104 
    105 private:
    106 
    107     BinaryNode<T> *root;                      //指向树根结点的指针
    108     
    109     int Create(BinaryNode<T> *p, T end, int flag);
    110 
    111     void remove(const T & x, BinaryNode<T> * & t, int rh);
    112 
    113     bool contains(const T & x, BinaryNode<T> *t) const;
    114 
    115     BinaryNode<T> * getNode(const T &x, BinaryNode<T> *t);
    116     
    117     T getParents(BinaryNode<T> *p, const T& e) const;
    118 
    119     void makeEmpty(BinaryNode<T> * & t);
    120     //利用 递归 算法 计算树的 深度 
    121     int Depth(BinaryNode<T> * t, int level, int &depth);
    122     //利用 递归 算法 计算树的 高度
    123     void CountLeaf(BinaryNode<T> * t, int &count);
    124 
    125 
    126     void PreprintTree(BinaryNode<T> * t) const;           //先序遍历 
    127     void InprintTree(BinaryNode<T> *t) const;             //中序遍历   
    128     void PostprintTree(BinaryNode<T> * t) const;          //后序遍历
    129     void LevelprintTree(BinaryNode<T> * t) const;          //层次遍历 
    130 
    131     void PreprintTree_N(BinaryNode<T> * t) const;          //非递归先序遍历
    132     void InprintTree_N(BinaryNode<T> * t) const;           //非递归中序遍历二叉树 
    133     void PostprintTree_N(BinaryNode<T> * t) const;         //非递归后序遍历二叉树 
    134     void DisplayTreeShape(BinaryNode<T> *bt, int level) const;    //二叉树的树形显示算法 
    135 
    136 
    137     BinaryNode<T> * clone(BinaryNode<T> * t) const;
    138 };
    139 
    140 template<typename T>
    141 bool BinarySearchTree<T>::contains(const T& x) const
    142 {
    143     return contains(x, root);
    144 }
    145 
    146 template<typename T>
    147 bool BinarySearchTree<T>::contains(const T & x, BinaryNode<T> *t) const
    148 {
    149     bool judge;
    150     if (t) {
    151         if (t->element == x)
    152             return true;
    153         judge = contains(x, t->left);
    154         if (judge) return true;
    155         judge = contains(x, t->right);
    156         if (judge) return true;
    157     }
    158     return false;
    159 }
    160 
    161 template<typename T>
    162 BinaryNode<T>* BinarySearchTree<T>::getNode(const T & x, BinaryNode<T> *t)
    163 {
    164     BinaryNode<T>* ptemp;
    165     if (t)
    166     {
    167         if (t->element == x) return t;
    168         ptemp = getNode(x, t->left);
    169         if (ptemp) return ptemp;
    170         ptemp = getNode(x, t->right);
    171         if (ptemp) return ptemp;    
    172     } 
    173     return nullptr;
    174 }
    175 
    176 template<typename T>
    177 T BinarySearchTree<T>::getParents(BinaryNode<T> *p, const T& e) const
    178 {
    179     const int maxn = 1024;
    180     BinaryNode<T> *Queue[maxn], *ptemp;
    181     int front = 0, rear = 0;
    182     if (p != nullptr && e != root->element) //为空,没有父节点, 且不为根结点 
    183     {
    184         Queue[rear++] = p;               //让根结点入队列,rear加1 
    185         while (front != rear)            //栈不为空 
    186         {
    187             ptemp = Queue[front++];      //将队列的结点依次出队
    188             if ((ptemp->left && ptemp->right->element == e )|| (ptemp->right && ptemp->left->element == e))
    189                 return ptemp->element;   //如果是,则返回 
    190             else 
    191             {
    192                 if (ptemp->left) Queue[rear++] = ptemp->left;    //左结点不为空,则入栈 
    193                 if (ptemp->right) Queue[rear++] = ptemp->right;  //右不为空,则入栈 
    194             }
    195         }
    196     }
    197     return -1; 
    198 }
    199 
    200 
    201 template<typename T>
    202 void BinarySearchTree<T>::RootCreate(const T& end)       //创建二叉树 
    203 {
    204     cout << "请按先序序列的顺序输入二叉树,-1为空指针域标志:" << endl;
    205     BinaryNode<T> *p;
    206     int x;
    207     cin >> x;
    208     if (x == end) return;
    209     p = new BinaryNode<T>(x, nullptr, nullptr);
    210     root = p;
    211     Create(p, end, 1);
    212     Create(p, end, 2);
    213 }
    214 
    215 template<typename T>
    216 int BinarySearchTree<T>::Create(BinaryNode<T> *p, T end, int flag)
    217 {
    218     BinaryNode<T> *t;
    219     T x;
    220     cin >> x;
    221     if (x != end)
    222     {//子节点的左右结点先赋值 
    223         t = new BinaryNode<T>(x, nullptr, nullptr);
    224         if (flag == 1) p->left = t;    //标志i=1,代表左孩子
    225         if (flag == 2) p->right = t;   //i=2结点为右孩子 
    226         Create(t, end, 1);             //递归调用,直到 x == end 
    227         Create(t, end, 2);
    228     }
    229     return 0;
    230 }
    231 
    232 template<typename T>
    233 void BinarySearchTree<T>::remove(const T &x)
    234 {
    235     remove(x, root, 1);
    236     remove(x, root, 2);
    237 }
    238 
    239 /************************************************************************/
    240 /* x is item to remove                                                  */
    241 /* t is the node that roots the subtree                                 */
    242 /* Set the new root of the subtree                                      */
    243 /* 1.结点是一片树叶时 -- 可被立即删除*/
    244 /* 2.结点有一个儿子, 则该结点可以在其父节点调整他的链 以绕过该结点后被删除 */
    245 /* 3.结点有两个儿子, 则其右子树的最小数据代替该结点的数据,并递归删除那个结点 */
    246 /* 注: 右子树中的最小的结点不可能有左结点                               */
    247 /************************************************************************/
    248 template<typename T>
    249 void BinarySearchTree<T>::remove(const T &x, BinaryNode<T> * & t, int rh)
    250 {
    251     if (t == nullptr) return;
    252     if (t->element == x && rh == 1)
    253     {
    254         makeEmpty(t->left);
    255     }
    256     else {
    257         makeEmpty(t->right);
    258     }
    259     remove(x, t->left, rh);
    260     remove(x, t->right, rh);
    261 }
    262 
    263 /************************************************************************/
    264 ///* Destructor for the tree
    265 /************************************************************************/
    266 template<typename T>
    267 BinarySearchTree<T>::~BinarySearchTree()
    268 {
    269     makeEmpty();
    270 }
    271 
    272 template<typename T>
    273 void BinarySearchTree<T>::makeEmpty()       //公有函数
    274 {
    275     makeEmpty(root);
    276 }
    277 
    278 /************************************************************************/
    279 ///* Internal method to make subtree empty -- 私有函数
    280 /************************************************************************/
    281 template<typename T>
    282 void BinarySearchTree<T>::makeEmpty(BinaryNode<T> * & t)
    283 {
    284     if (t != nullptr)
    285     {
    286         makeEmpty(t->left);
    287         makeEmpty(t->right);
    288         delete t;
    289     }
    290     t = nullptr;
    291 }
    292 
    293 /************************************************************************/
    294 ///* Deep copy
    295 /************************************************************************/
    296 template<typename T>
    297 const BinarySearchTree<T>& BinarySearchTree<T>::operator = (const BinarySearchTree &rhs)
    298 {
    299     if (this != &rhs) {
    300         makeEmpty();
    301         root = clone(rhs.root);
    302     }
    303     return *this;
    304 }
    305 
    306 /************************************************************************/
    307 ///* Internal method to clone subtree.  --  递归复制结点
    308 /************************************************************************/
    309 template<typename T>
    310 BinaryNode<T>* BinarySearchTree<T>::clone(BinaryNode<T> * t) const
    311 {
    312     if (t == nullptr)
    313         return nullptr;
    314     return new BinaryNode<T>(t->element, clone(t->left), clone(t->right));
    315 }
    316 
    317 //利用递归计算树的深度 
    318 template<typename T>
    319 int BinarySearchTree<T>::Depth()
    320 {
    321     BinaryNode<T> *t = root;
    322     int depth = 0;
    323     if (root == nullptr)
    324         return 0;
    325     Depth(t, 1, depth);
    326     return depth;
    327 }
    328 
    329 //由public的函数Depth调用, 完成树的深度的计算,p是根结点,Level是层,depth用来返回树的深度 
    330 template<typename T>
    331 int BinarySearchTree<T>::Depth(BinaryNode<T> *t, int level, int &depth)
    332 {
    333     if (level > depth) depth = level;                  //层数
    334     if (t->left) Depth(t->left, level + 1, depth);     //递归遍历左子树,且层数加1 
    335     if (t->right) Depth(t->right, level + 1, depth);   //递归遍历右子树, 且层数加1 
    336     return 0;
    337 }
    338 
    339 template<typename T>
    340 //利用 递归 算法 计算树的 高度
    341 void BinarySearchTree<T>::CountLeaf(BinaryNode<T> * t, int &count)
    342 {
    343     if (t == nullptr) return;               //为空时,退出
    344 
    345     //    CountLeaf(t->left, count);
    346     //    CountLeaf(t->right, count); 
    347     if (!(t->left) && !(t->right)) {        //儿子为空时 
    348         count++;
    349     }
    350     CountLeaf(t->left, count);
    351     CountLeaf(t->right, count);
    352 }
    353 
    354 
    355 /************************************************************************/
    356 ///* printTree   ---    前序遍历 
    357 /************************************************************************/
    358 template<typename T>
    359 void BinarySearchTree<T>::PreprintTree(BinaryNode<T> * t) const
    360 {
    361     if (t != nullptr) {
    362         cout << t->element << ' ';
    363         PreprintTree(t->left);
    364         PreprintTree(t->right);
    365     }
    366 }
    367 
    368 //中序遍历 
    369 template<typename T>
    370 void BinarySearchTree<T>::InprintTree(BinaryNode<T> * t) const
    371 {
    372     if (t != nullptr) {
    373         InprintTree(t->left);
    374         cout << t->element << ' ';
    375         InprintTree(t->right);
    376     }
    377 }
    378 
    379 //后序遍历 
    380 template<typename T>
    381 void BinarySearchTree<T>::PostprintTree(BinaryNode<T> * t) const
    382 {
    383     if (t != nullptr) {
    384         PostprintTree(t->left);
    385         PostprintTree(t->right);
    386         cout << t->element << ' ';
    387     }
    388 }
    389 
    390 //利用队列Queue层次遍历二叉树 
    391 template<typename T>
    392 void BinarySearchTree<T>::LevelprintTree(BinaryNode<T> * t) const
    393 {
    394     const int maxn = 1024;
    395     BinaryNode<T> *Queue[maxn];                          //一维数组作为队列 
    396     BinaryNode<T> *tmp;
    397     int front = 0, rear = 0;                             //队列初始为空 
    398     if (root) {
    399         Queue[rear++] = root;                            //二叉树的根结点指针入队列 
    400         while (front != rear)
    401         {
    402             tmp = Queue[front++];                        //队首的元素出队列
    403             if (tmp) cout << tmp->element << ' ';        //输出结点值
    404             if (tmp->left) Queue[rear++] = tmp->left;
    405             if (tmp->right) Queue[rear++] = tmp->right;
    406         }
    407     }
    408 }
    409 
    410 //先序遍历 (DLR)
    411 template<typename T>
    412 void BinarySearchTree<T>::PreprintTree_N(BinaryNode<T> * t) const          //非递归先序遍历
    413 {
    414     const int maxn = 1024;
    415     BinaryNode<T> *Stack[maxn];
    416     int top = 0;
    417     BinaryNode<T> *tmp = root;            //将根结点的指针赋值给tmp 
    418 
    419     //    cout << "Debug :
    ";
    420     while (tmp || top != 0)
    421     {
    422         //        cout << "debug : 
    ";
    423         while (tmp) {
    424             cout << tmp->element << ' ';
    425             Stack[top++] = tmp;           //右孩子入栈 
    426             tmp = tmp->left;              //一直递归到最左的结点 
    427         }
    428         if (top) {                        //栈不为空, 从栈中取出一个结点指针 
    429             tmp = Stack[--top];
    430             tmp = tmp->right;
    431         }
    432     }
    433 }
    434 
    435 //中序非递归遍历二叉树 (LDR)
    436 template<typename T>
    437 void BinarySearchTree<T>::InprintTree_N(BinaryNode<T> * t) const           //非递归中序遍历二叉树 
    438 {
    439     const int maxn = 1024;
    440     BinaryNode<T> *Stack[maxn];
    441     int top = 0;
    442     BinaryNode<T> *tmp = root;
    443 
    444     while (tmp || top != 0)
    445     {
    446         while (tmp) {                  //迭代到最左的子树 
    447             Stack[top++] = tmp;        //左子树入栈 
    448             tmp = tmp->left;
    449         } 
    450         if (top) {
    451             tmp = Stack[--top];            //出栈最左的子树 
    452             cout << tmp->element << ' ';   //输出该元素 
    453             tmp = tmp->right;              //并指向右结点开始迭代 
    454         }
    455     }
    456 
    457 }
    458 
    459 //非递归后序遍历二叉树 (LRD)
    460 template<typename T>
    461 void BinarySearchTree<T>::PostprintTree_N(BinaryNode<T> * t) const
    462 {
    463     const int maxn = 1024;
    464     struct Mystack {
    465         BinaryNode<T> * link;
    466         int flag;
    467     };
    468 
    469     Mystack Stack[maxn];
    470     BinaryNode<T> * p = root, *tmp;
    471 
    472     if (root == nullptr) return;
    473 
    474     int top = -1,                  //栈顶初始化 
    475         sign = 0;                  //为结点tmp 的标志量 
    476 
    477     while (p != nullptr || top != -1)
    478     {
    479         while (p != nullptr)       //遍历到最左 
    480         {
    481             Stack[++top].link = p; //并且一直入栈 
    482             Stack[top].flag = 1;   //设置flag为第一次入栈 
    483             p = p->left;
    484         }
    485 
    486         if (top != -1)
    487         {
    488             tmp = Stack[top].link;
    489             sign = Stack[top].flag;
    490             top--;                 //出栈 
    491 
    492             if (sign == 1)         //结点第一次进栈 
    493             {
    494                 top++;
    495                 Stack[top].link = tmp;
    496                 Stack[top].flag = 2;            //标记为第二次出栈 
    497                 p = tmp->right;
    498             }
    499             else {                                //第二次出栈就输出 
    500                 cout << tmp->element << ' ';      //访问该结点数据域 
    501                 p = nullptr;
    502             }
    503         }
    504 
    505     }
    506 
    507 }
    508 
    509 //树形显示二叉树,也是中序遍历 
    510 template<typename T>
    511 void BinarySearchTree<T>::DisplayTreeShape(BinaryNode<T> *bt, int level) const
    512 {    
    513     if (bt)                                         //二叉树的树形显示算法
    514     {
    515         DisplayTreeShape(bt->right, level + 1);     //空二叉树不显示
    516         cout << endl;
    517         for (int i = 0; i < level - 1; i++)
    518             cout << "   ";                            //确保在第level列显示结点 
    519         cout << bt->element;
    520         DisplayTreeShape(bt->left, level + 1);        //显示左子树
    521     }
    522 }
    523 
    524 //先序(preorder) -- 中序(inorder)  ===>   得到后序遍历(postorder)
    525 //先序为了得到根结点,  中序为了得到左右两个子序列 
    526 template<typename T>
    527 void BinaryTreeFromOrderings(const T *inorder, const T *preorder, int length)
    528 {
    529     if (length == 0) return;
    530     T node_value = *preorder;                 //得到先序序列的第一个元素 ==> 根结点 
    531     int rootIndex = 0;                        //根结点的索引 
    532     for (; rootIndex < length; rootIndex++) { //在中序序列中,遍历到(先序遍历的)根结点的地方终止 
    533         if (inorder[rootIndex] == *preorder)  
    534             break;
    535     }
    536 
    537     /******************* Left Root Right *********************/
    538     //left   -- 中序遍历开始的位置,后序遍历开始的位置 可以遍历的总长度 
    539     BinaryTreeFromOrderings(inorder, preorder + 1, rootIndex);
    540     //Right
    541     BinaryTreeFromOrderings(inorder + rootIndex + 1, preorder + rootIndex + 1, length - (rootIndex + 1));    
    542     cout << node_value << ' ';
    543 }
    544 
    545 
    546 int main()
    547 {
    548     int testData;
    549     BinarySearchTree<int> test;
    550     cout << "创建树: 
    ";
    551     test.RootCreate(-1);
    552 
    553     cout << "
    全部元素为: 
    ";
    554     test.PreprintTree();
    555 
    556     cout << endl;
    557 
    558     cout << "输入查找元素: 
    ";
    559     cin >> testData;
    560     cout << "是否包含 " << testData << " : " << test.contains(testData) << endl;
    561     
    562     cout << testData << "的父亲是:	";
    563     cout << test.getParents(testData) << endl;
    564 
    565     cout << endl;
    566     cout << "输入修改元素: 
    ";
    567     cin >> testData;
    568     if (test.getNode(testData, 1000))
    569         cout << "OK !
    ";
    570     test.PreprintTree();
    571     cout << "
    ";
    572 
    573     cout << "
    树的高度: " << test.Depth() << endl;
    574     cout << "
    叶子的个数: " << test.CountLeaf() << endl;
    575     cout << endl;
    576 
    577     cout << "先序遍历树元素: 
    ";
    578     test.PreprintTree();
    579 
    580     cout << "
    
    中序遍历树元素: 
    ";
    581     test.InprintTree();
    582 
    583     cout << "
    
    后序遍历树元素: 
    ";
    584     test.PostprintTree();
    585 
    586     cout << "
    
    层次遍历树元素: 
    ";
    587     test.LevelprintTree();
    588 
    589     cout << "
    
    先序遍历树元素(非递归): 
    ";
    590     test.PreprintTree_N();
    591 
    592     cout << "
    
    中序遍历树元素(非递归): 
    ";
    593     test.InprintTree_N();
    594 
    595     cout << "
    
    后序遍历树元素(非递归): 
    ";
    596     test.PostprintTree_N();
    597 
    598     cout << "
    
    二叉树的树形显示算法(下面是逆时针旋转了90°的树): 
    ";
    599     test.DisplayTreeShape(43);
    600 
    601     cout << endl;
    602     
    603     const char* pr = "ABCDEFGHI";            //GDAFEMHZ
    604     const char* in = "BCAEDGHFI";            //ADEFGHMZ
    605     BinaryTreeFromOrderings(in, pr, strlen(pr));
    606     
    607     cout << endl;    
    608     
    609     return 0;
    610 }
  • 相关阅读:
    springmvc与Ajax交互
    springmvc请求参数获取的几种方法
    struts2进阶篇(2)
    mysql explain用法
    struts2基础篇(1)
    struts2工作原理
    PHP 数组的拷贝是按值传递 or 按引用传递
    js中使用cookie
    Yii rules常用规则
    js倒计时发送验证码按钮
  • 原文地址:https://www.cnblogs.com/douzujun/p/6017667.html
Copyright © 2011-2022 走看看