基于c++ STL的二叉树非递归遍历算法(前序中序后序)

参考链接:http://blog.csdn.net/j_anson/article/details/49671523


二叉树的实现,使用栈构建一棵二叉树,然后求树高,递归先序遍历,中序遍历,后序遍历,访问左节点,访问右节点,非递归先序遍历输出,非递归中序遍历输出,非递归后序遍历输出。

[cpp]  view plain  copy
  1. /* 
  2. 二叉树实现 
  3. */  
  4. #include<iostream>  
  5. #include<string>  
  6. #include<stack>  
  7. #include<fstream>  
  8. using namespace std;  
  9.   
  10. const int MAX_N = 100;  
  11. //数据节点  
  12. class Node  
  13. {  
  14. public:  
  15.     char data;//数据  
  16.     class Node *lchild;//左节点  
  17.     class Node *rchild;//右节点  
  18. };  
  19.   
  20. //二叉树  
  21. class Tree  
  22. {  
  23. public:  
  24.     Tree(){}  
  25.     ~Tree(){}  
  26.   
  27.     //先序遍历非递归算法  
  28.     void Disp()  
  29.     {  
  30.         if (t == NULL)  
  31.         {  
  32.             return;  
  33.         }  
  34.         stack<Node *> m_stack;  
  35.         m_stack.push(t);  
  36.         while (!m_stack.empty())  
  37.         {  
  38.             Node *p = m_stack.top();//赋值一份当前双亲节点  
  39.             cout << p->data << ends;  
  40.             m_stack.pop();  
  41.             if (p->rchild)//先存储右子树,确保先输出左子树  
  42.             {  
  43.                 m_stack.push(p->rchild);  
  44.             }  
  45.             if (p->lchild)//后存储左子树  
  46.             {  
  47.                 m_stack.push(p->lchild);  
  48.             }  
  49.         }  
  50.       
  51.     }  
  52.   
  53.     //非递归中序遍历二叉树  
  54.     void DispMid()  
  55.     {  
  56.         if (t == NULL)  
  57.         {  
  58.             return;  
  59.         }  
  60.         Node *p = t;  
  61.         stack<Node *>m_stack;  
  62.         while (p != NULL || !m_stack.empty())  
  63.         {  
  64.             while (p != NULL)//一路直走至左下角  
  65.             {  
  66.                 m_stack.push(p);  
  67.                 p = p->lchild;  
  68.             }  
  69.             if (!m_stack.empty())  
  70.             {  
  71.                 p = m_stack.top();//备份当前栈顶地址  
  72.                 m_stack.pop();  
  73.                 cout << p->data << ends;  
  74.                 p = p->rchild;  
  75.             }  
  76.         }  
  77.     }  
  78.   
  79.     //非递归后序遍历二叉树  
  80.     void DispBehid()  
  81.     {  
  82.         if (t == NULL)  
  83.         {  
  84.             return;  
  85.         }  
  86.         Node *pre = NULL, *p = t;  
  87.         stack<Node *>m_stack;  
  88.         while (p != NULL || !m_stack.empty())  
  89.         {  
  90.             while (p != NULL)//一路直走至左下角  
  91.             {  
  92.                 m_stack.push(p);  
  93.                 p = p->lchild;  
  94.             }  
  95.             p = m_stack.top();  
  96.             //右子树为空或者已访问,输出当前节点  
  97.             if (p->rchild == NULL || p->rchild == pre)  
  98.             {  
  99.                 cout << p->data << ends;  
  100.                 pre = p;//将当前结点地址赋值pre作为下一次判断标志,防止重复访问  
  101.                 m_stack.pop();  
  102.                 p = NULL;//p赋值空以便访问右子树  
  103.             }  
  104.             else  
  105.             {  
  106.                 p = p->rchild;//访问子树的右子树  
  107.             }  
  108.         }  
  109.     }  
  110.     //构建二叉树  
  111.     void Create(string name)  
  112.     {  
  113.         ifstream readfile;  
  114.         string str;  
  115.         readfile.open(name);  
  116.         if (readfile.is_open())  
  117.         {  
  118.             getline(readfile, str);//读取一行  
  119.         }  
  120.         readfile.close();  
  121.         CreateNode(str);//构建二叉树  
  122.     }  
  123.   
  124.     //递归先序遍历输出二叉树  
  125.     void display()  
  126.     {  
  127.         cout << "Output:";  
  128.         output(t);  
  129.         cout << endl;  
  130.     }  
  131.   
  132.     //递归中序遍历输出二叉树  
  133.     void displayMid()  
  134.     {  
  135.         cout << "Output:";  
  136.         outputMid(t);  
  137.         cout << endl;  
  138.     }  
  139.   
  140.     //递归后序遍历输出二叉树  
  141.     void displayBhind()  
  142.     {  
  143.         cout << "output:";  
  144.         outputBhind(t);  
  145.         cout << endl;  
  146.     }  
  147.     //二叉树高度  
  148.     void Height()  
  149.     {  
  150.         int height = get_height(t);  
  151.         cout << "Height: " << height << endl;  
  152.     }  
  153.   
  154.     //输出叶子节点值  
  155.     void display_leaf()  
  156.     {  
  157.         cout << "Leaves: ";  
  158.         output_leaf(t);  
  159.         cout << endl;  
  160.     }  
  161. private:  
  162.     Node *t;  
  163.   
  164.     //构建二叉树  
  165.     void CreateNode(string str)  
  166.     {  
  167.         stack<Node *> m_stack;  
  168.         Node *p;  
  169.         int k;  
  170.         while (str.length() != 0)  
  171.         {  
  172.             //若当前为'(',将双亲节点推入栈,下一位存储的p值作为左节点处理  
  173.             if (str[0] == '(')  
  174.             {  
  175.                 m_stack.push(p); k = 1;  
  176.             }  
  177.             //为右括号则栈顶退出一位  
  178.             else if (str[0] == ')')  
  179.             {  
  180.                 m_stack.pop();  
  181.             }  
  182.             //为',',则下一个字符作右节点处理  
  183.             else if (str[0] == ',')  
  184.             {  
  185.                 k = 2;  
  186.             }  
  187.             //存储值用作双亲结点  
  188.             else  
  189.             {  
  190.                 p = (Node *)malloc(sizeof(Node));  
  191.                 p->data = str[0];  
  192.                 p->lchild = p->rchild = NULL;  
  193.                 //树根为空时,将第一个节点作为树根并赋值给私有成员变量  
  194.                 if (t == NULL)  
  195.                 {  
  196.                     t = p;  
  197.                 }  
  198.                 //树根不为空  
  199.                 else  
  200.                 {  
  201.                     if (k == 1)//作为左节点处理,将栈中双亲节点的左指针指向当前节点  
  202.                     {  
  203.                         m_stack.top()->lchild = p;  
  204.                     }  
  205.                     else//作为右节点处理  
  206.                     {  
  207.                         m_stack.top()->rchild = p;  
  208.                     }  
  209.                 }  
  210.             }  
  211.             //重构串,除去首字符,并将串长度减小1  
  212.             str.assign(str.substr(1, str.length() - 1));  
  213.         }  
  214.     }  
  215.   
  216.     //递归先序遍历输出二叉树  
  217.     void output(Node *t)  
  218.     {  
  219.         if (t != NULL)//当树根不为空时  
  220.         {  
  221.             cout << t->data;//输出  
  222.             if (t->lchild != NULL || t->rchild != NULL)//左/右结点不为空时递归到下一层  
  223.             {  
  224.                 cout << "(";  
  225.                 output(t->lchild);  
  226.                 if (t->rchild != NULL)//当左节点遍历结束后,左节点递归返回一层,递归右节点  
  227.                 {  
  228.                     cout << ",";  
  229.                 }  
  230.                 output(t->rchild);  
  231.                 cout << ")";  
  232.             }  
  233.         }  
  234.     }  
  235.   
  236.     //递归中序遍历二叉树  
  237.     void outputMid(Node *t)  
  238.     {  
  239.         if (t == NULL)  
  240.         {  
  241.             return;  
  242.         }  
  243.         else  
  244.         {  
  245.             cout << "(";  
  246.             outputMid(t->lchild);  
  247.             if (t->rchild != NULL)  
  248.             {  
  249.                 cout << ",";  
  250.             }  
  251.             cout << t->data;  
  252.             outputMid(t->rchild);  
  253.             cout << ")";  
  254.         }  
  255.     }  
  256.   
  257.     //递归后序遍历输出二叉树  
  258.     void outputBhind(Node *t)  
  259.     {  
  260.         if (!t)  
  261.         {  
  262.             return;  
  263.         }  
  264.         else  
  265.         {  
  266.             cout << "(";  
  267.             outputBhind(t->lchild);  
  268.             if (t->rchild != NULL)  
  269.             {  
  270.                 cout << ",";  
  271.             }  
  272.             outputBhind(t->rchild);  
  273.             cout << t->data;  
  274.             cout << ")";  
  275.         }  
  276.     }  
  277.     //求树高  
  278.     int get_height(Node *t)  
  279.     {  
  280.         int leftheight, rightheight;  
  281.         if (t == NULL)//递归至不存在子节点时返回0  
  282.         {  
  283.             return 0;  
  284.         }  
  285.         else  
  286.         {  
  287.             leftheight = get_height(t->lchild);//递归求左子树高度  
  288.             rightheight = get_height(t->rchild);//递归其右子树高度  
  289.             return leftheight > rightheight ? leftheight+1 : rightheight+1;//递归返回时返回最大值  
  290.         }  
  291.     }  
  292.   
  293.     //查找左节点  
  294.     Node *leftchild(Node *p)  
  295.     {  
  296.         return p->lchild;  
  297.     }  
  298.   
  299.     //查找右节点  
  300.     Node *rightchild(Node *p)  
  301.     {  
  302.         return p->rchild;  
  303.     }  
  304.   
  305.     //输出叶子节点  
  306.     void output_leaf(Node *t)  
  307.     {  
  308.         if (t != NULL)//树根不为空时  
  309.         {  
  310.             //当前节点没有子节点时输出节点数据  
  311.             if (t->lchild == NULL&&t->rchild == NULL)  
  312.             {  
  313.                 cout << t->data << ends;  
  314.             }  
  315.             output_leaf(t->lchild);//递归左子树  
  316.             output_leaf(t->rchild);//递归右子树  
  317.         }  
  318.     }  
  319. };  
  320.   
  321.   
  322. int main()  
  323. {  
  324.     Tree m_tree;  
  325.     m_tree.Create("data");  
  326.     m_tree.display();//递归先序输出  
  327.     m_tree.displayMid();//递归中序输出  
  328.     m_tree.displayBhind();//递归后序输出  
  329.     m_tree.Height();//树高  
  330.     m_tree.display_leaf();//叶子节点  
  331.     m_tree.Disp();//非递归先序遍历  
  332.     cout << endl;  
  333.     m_tree.DispMid();//非递归中序遍历  
  334.     cout << endl;  
  335.     m_tree.DispBehid();//非递归后序遍历  
  336.     cout << endl;  
  337.     return 0;  
  338. }  

一次测试结果:


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值