zoukankan      html  css  js  c++  java
  • 二叉树非递归遍历

    上码:

      1 #include <iostream>
      2 #include <string>
      3 #include <stack>
      4 #include <queue>
      5 using namespace std;
      6 
      7 template<class T>
      8 struct BiNode {
      9     T data;
     10     BiNode<T> *lchild, *rchild;//左子树、右子树
     11 };
     12 
     13 template<class T>
     14 class BiTree
     15 {
     16 public:
     17     BiTree();                                //构造函数,初始化二叉树,前序序列由键盘输入
     18     ~BiTree();                                //析构函数,释放二叉链表中的各结点的存储空间
     19     BiNode<T>* Getroot();                    //获得指向根节点的指针
     20     void PreOrder(BiNode<T>* root);            //前序遍历二叉树
     21     void InOrder(BiNode<T>* root);            //中序遍历二叉树
     22     void PostOrder(BiNode<T>* root);        //后序遍历二叉树
     23     void LeverOrder(BiNode<T>* root);        //层序遍历二叉树
     24 
     25     void NonPreOrder(BiNode<T>* root);
     26     void NonInOrder(BiNode<T>* root);
     27     void NonPostOrder(BiNode<T>* root);
     28 private:
     29     BiNode<T> *root;                        //指向根节点的头指针
     30     BiNode<T> *Create();                        //有参构造函数调用
     31     void ReLease(BiNode<T> *root);            //析构函数调用
     32 };
     33 template<class T>
     34 BiTree<T>::BiTree() {
     35     this->root = Create();                    //创建对象时,构造函数被调用后,调用Great函数进行初始化
     36 }
     37 
     38 template<class T>
     39 BiTree<T>::~BiTree() {
     40     ReLease(root);                            //调用ReLease释放二叉树链表
     41 }
     42 
     43 template<class T>
     44 BiNode<T>* BiTree<T>::Getroot() {
     45     return root;                            //返回根节点地址
     46 }
     47 
     48 template<class T>
     49 void BiTree<T>::PreOrder(BiNode<T>* root) {
     50     if (root == NULL)
     51         return;
     52     cout << root->data << " ";
     53     PreOrder(root->lchild);                    //前序遍历二叉树(根,左,右)
     54     PreOrder(root->rchild);
     55 }
     56 
     57 template<class T>
     58 void BiTree<T>::InOrder(BiNode<T> *root) {
     59     if (root == NULL)
     60         return;
     61     InOrder(root->lchild);                    //中序遍历二叉树(左,根,右)
     62     cout << root->data << " ";
     63     InOrder(root->rchild);
     64 }
     65 
     66 template<class T>
     67 void BiTree<T>::PostOrder(BiNode<T>* root) {
     68     if (root == NULL)
     69         return;
     70     PostOrder(root->lchild);                //后序遍历二叉树(左,右,根)
     71     PostOrder(root->rchild);
     72     cout << root->data << " ";
     73 }
     74 
     75 template<class T>
     76 void BiTree<T>::LeverOrder(BiNode<T>* root) {
     77     BiNode<T> *p;                            //层序遍历
     78     if (root == NULL)
     79         return;
     80     queue<BiNode<T>*> q;        
     81     q.push(root);
     82     while (!q.empty()) {
     83         p = q.front();
     84         cout << p->data << " ";
     85         q.pop();
     86         if (p->lchild != NULL) {
     87             q.push(p->lchild);
     88         }
     89         if (p->rchild != NULL) {
     90             q.push(p->rchild);
     91         }
     92     }
     93 }
     94 
     95 template<class T>
     96 BiNode<T>* BiTree<T>::Create() {
     97     BiNode<T>* root;                        //构造二叉树
     98     T ch;
     99     cout << "请输入创建的一颗二叉树的结点数据:" << endl;
    100     cin >> ch;
    101     if (ch == "#")
    102         root = NULL;
    103     else {
    104         root = new BiNode<T>;
    105         root->data = ch;
    106         root->lchild = Create();
    107         root->rchild = Create();
    108     }
    109     return root;
    110 }
    111 
    112 template<class T>
    113 void BiTree<T>::ReLease(BiNode<T>* root) {
    114     if (root != NULL) {                        //删除二叉树
    115         ReLease(root->lchild);
    116         ReLease(root->rchild);
    117         delete root;
    118     }
    119 }
    120 
    121 template<class T>
    122 void BiTree<T>::NonPreOrder(BiNode<T>* root) {
    123     if (root == NULL)
    124         return;
    125     stack<BiNode<T>*> s;
    126     BiNode<T> *p = root, *q;
    127     while (p != NULL || !s.empty())
    128     {
    129         if (p != NULL) {
    130             cout << p->data << ' ';
    131             s.push(p);
    132             p = p->lchild;
    133         }
    134         else {
    135             q = s.top();
    136             s.pop();
    137             p = q->rchild;
    138         }
    139     }
    140 }
    141 template<class T>
    142 void BiTree<T>::NonInOrder(BiNode<T>* root) {
    143     if (root == NULL)
    144         return;
    145     stack<BiNode<T>*> s;
    146     BiNode<T> *p = root, *q;
    147     while (!s.empty() || p != NULL)
    148     {
    149         while (p != NULL) {
    150             s.push(p);
    151             p = p->lchild;
    152         }
    153         if (!s.empty()) {
    154             q = s.top();
    155             s.pop();
    156             cout << q->data << ' ';
    157             p = q->rchild;
    158         }
    159 
    160     }
    161 
    162 }
    163 template<class T>
    164 void BiTree<T>::NonPostOrder(BiNode<T>* root) {
    165     if (root == NULL)
    166         return;
    167     stack<BiNode<T>*> s;
    168     stack<int> symbol;                    //visit 记录访问的次数0,1,与s栈一一对应
    169     BiNode<T> *p = root, *q;
    170     while (!s.empty() || p != NULL)
    171     {
    172         while (p != NULL) {
    173             s.push(p);
    174             symbol.push(0);                //对应位置入栈 0,表示未经访问
    175             p = p->lchild;
    176         }
    177                                         //栈不空,且栈顶元素未经访问
    178         if (!s.empty() && !symbol.top()) {
    179             symbol.pop();
    180             symbol.push(1);
    181 
    182             q = s.top();
    183             p = q->rchild;
    184         }
    185                                         //栈不空,且栈顶元素已经被访问
    186         else if (!s.empty() && symbol.top()) {
    187             //经过循环体 右子树结束
    188             while (symbol.top()) {        //清空栈中已被访问过的元素,即symbol为 1者
    189                 q = s.top();
    190                 cout << q->data << ' ';
    191                 s.pop();
    192 
    193                 symbol.pop();
    194                 if (!symbol.size())
    195                     break;
    196             }
    197 
    198             if (!s.empty()) {
    199                 symbol.pop();
    200                 symbol.push(1);
    201 
    202                 q = s.top();
    203                 p = q->rchild;
    204             }
    205             else {
    206                 p = NULL;
    207             }
    208         }
    209         else
    210             continue;
    211 
    212     }
    213 }
    214 
    215 int main()
    216 {
    217     BiTree<string> bt;//创建一棵树
    218     BiNode<string>* root = bt.Getroot();
    219     cout << "------前序遍历------" << endl;
    220     bt.PreOrder(root);
    221     cout << endl;
    222     cout << "------后序遍历------" << endl;
    223     bt.PostOrder(root);
    224     cout << endl;
    225     cout << "------中序遍历------" << endl;
    226     bt.InOrder(root);
    227     cout << endl;
    228     cout << "------层序遍历------" << endl;
    229     bt.LeverOrder(root);
    230     cout << endl;
    231     cout << "---非递归前序遍历---" << endl;
    232     bt.NonPreOrder(root);
    233     cout << endl;
    234     cout << "---非递归后序遍历---" << endl;
    235     bt.NonPostOrder(root);
    236     cout << endl;
    237     cout << "---非递归中序遍历---" << endl;
    238     bt.NonInOrder(root);
    239     cout << endl;
    240     return 0;
    241 }

    后序遍历有点蹩脚,需要注意几点细节,避免死循环陷阱。

  • 相关阅读:
    大数加法、乘法实现的简单版本
    hdu 4027 Can you answer these queries?
    zoj 1610 Count the Colors
    2018 徐州赛区网赛 G. Trace
    1495 中国好区间 尺取法
    LA 3938 动态最大连续区间 线段树
    51nod 1275 连续子段的差异
    caioj 1172 poj 2823 单调队列过渡题
    数据结构和算法题
    一个通用分页类
  • 原文地址:https://www.cnblogs.com/guoyujiang/p/12024600.html
Copyright © 2011-2022 走看看