利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离

原文地址:http://blog.csdn.net/forbes_zhong/article/details/51227747


利用栈实现二叉树的非递归遍历,并求二叉树的深度、叶子节点数、两个节点的最近公共祖先以及二叉树结点的最大距离,部分参考《剑指offer》这本书,其代码如下:

[cpp]  view plain  copy
  1. #include<iostream>  
  2. #include<vector>  
  3. #include<stack>  
  4. using namespace std;  
  5.   
  6. typedef struct BiNode //定义一棵二叉树  
  7. {  
  8.     char val;  
  9.     struct BiNode *left;  
  10.     struct BiNode *right;  
  11.     BiNode(char x) :val(x), left(NULL), right(NULL){}  
  12. }BiNode,*BiTree;  
  13.   
  14. void CreateBiTree(BiTree &T)//前序创建一颗二叉树  
  15. {  
  16.     char c;  
  17.     cin >> c;  
  18.     if ('#' == c)  
  19.         T=NULL;  
  20.     else  
  21.     {  
  22.         T = (BiNode* ) malloc(sizeof(BiNode));  
  23.         T->val = c;  
  24.         CreateBiTree(T->left);  
  25.         CreateBiTree(T->right);  
  26.     }  
  27. }  
  28.   
  29. //二叉树的非递归遍历(前序、中序、后序及层序)  
  30. void PreOrder(BiTree& T)//前序遍历,非递归  
  31. {  
  32.     if (T == NULL)  
  33.         return;  
  34.     vector<BiNode*> S;  
  35.     BiNode *p = T;  
  36.     while (p != NULL || !S.empty())  
  37.     {  
  38.         while (p != NULL)  
  39.         {  
  40.             cout << p->val << " ";  
  41.             S.push_back(p);  
  42.             p = p->left;  
  43.         }  
  44.         if (!S.empty())  
  45.         {  
  46.             p = S[S.size() - 1];  
  47.             S.pop_back();  
  48.             p = p->right;  
  49.         }  
  50.     }  
  51.     cout << endl;  
  52. }  
  53.   
  54. void InOrder(BiTree& T)//中序遍历,非递归  
  55. {  
  56.     if (T == NULL)  
  57.         return;  
  58.     vector<BiNode*> S;  
  59.     BiNode *p = T;  
  60.     while ( p != NULL || !S.empty())  
  61.     {  
  62.         while (p != NULL)  
  63.         {  
  64.             S.push_back(p);  
  65.             p = p->left;  
  66.         }  
  67.         if (!S.empty())  
  68.         {  
  69.             p = S[S.size() - 1];  
  70.             cout << p->val << " ";  
  71.             S.pop_back();  
  72.             p = p->right;  
  73.         }  
  74.     }  
  75.     cout << endl;  
  76. }  
  77.   
  78. void PostOrder(BiTree &T)//后序遍历(双栈法),非递归  
  79. {  
  80.     if (T == NULL)  
  81.         return;  
  82.     vector<BiNode*> S1,S2;  
  83.     BiNode *p ;//当前指针所在结点  
  84.     S1.push_back(T);  
  85.     while (!S1.empty())  
  86.     {  
  87.         p = S1[S1.size() - 1];  
  88.         S1.pop_back();  
  89.         S2.push_back(p);  
  90.         if (p->left)  
  91.             S1.push_back(p->left);  
  92.         if (p->right)  
  93.             S1.push_back(p->right);  
  94.     }  
  95.     while (!S2.empty())  
  96.     {  
  97.         cout << S2[S2.size() - 1]->val << " ";  
  98.         S2.pop_back();  
  99.     }  
  100.     cout << endl;  
  101. }  
  102.   
  103. void LevelOrder(BiTree &T)//非递归层序遍历,可选择按层输出结点,也可用于计算二叉树的深度  
  104. {  
  105.     if (T == NULL)  
  106.         return;  
  107.     vector<BiNode*> S;  
  108.     S.push_back(T);  
  109.     //int depth = 0;//统计二叉树的深度  
  110.     int cur = 0;  
  111.     int last = 1;  
  112.     while (cur < S.size())  
  113.     {  
  114.         last = S.size();  
  115.         while (cur < last)  
  116.         {  
  117.             cout << S[cur]->val << " ";  
  118.             if (S[cur]->left != NULL)  
  119.                 S.push_back(S[cur]->left);  
  120.             if (S[cur]->right != NULL)  
  121.                 S.push_back(S[cur]->right);  
  122.             ++cur;  
  123.         }  
  124.         //cout << endl;如果需要按层输出每一层的结点则取消此行注释  
  125.         //depth++;//如果要求二叉树的深度,只需在此统计输出了多少次endl就可以  
  126.     }  
  127.     cout << endl;  
  128. }  
  129.   
  130. void LevelOrder2(BiTree &T)//层序遍历,非递归(双栈法),奇偶层数存储有区别时可实现之字形打印  
  131. {  
  132.     if (T == NULL)  
  133.         return;  
  134.     stack<BiNode*> Levels[2];  
  135.     int cur = 0;//奇数行  
  136.     int next = 1;//偶数行  
  137.     Levels[cur].push(T);  
  138.     while (!Levels[0].empty() || !Levels[1].empty())  
  139.     {  
  140.         BiNode *p = Levels[cur].top();  
  141.         Levels[cur].pop();  
  142.         cout << p->val << " ";  
  143.         if (cur == 0)//奇数层顺序存储  
  144.         {  
  145.             if (p->left != NULL)  
  146.                 Levels[next].push(p->left);  
  147.             if (p->right != NULL)  
  148.                 Levels[next].push(p->right);  
  149.         }  
  150.         else//偶数层逆序存储  
  151.         {  
  152.             if (p->right != NULL)  
  153.                 Levels[next].push(p->right);  
  154.             if (p->left != NULL)  
  155.                 Levels[next].push(p->left);  
  156.         }  
  157.         if (Levels[cur].empty())  
  158.         {  
  159.             //cout << endl;//换行,如果不换行可以注释掉这条  
  160.             cur = 1 - cur;  
  161.             next = 1 - next;  
  162.         }  
  163.     }  
  164.     cout << endl;  
  165. }  
  166.   
  167. void GetNodePath(BiNode* T, BiNode* Node, vector<BiNode*>& Path,int &found)//获取二叉树中从根节点到指定节点的路径   
  168. {  
  169.     if (T == NULL)  
  170.         return;  
  171.     Path.push_back(T);  
  172.     if (T == Node)  
  173.         found = 1;  
  174.     if (!found)  
  175.     {  
  176.         GetNodePath(T->left, Node, Path, found);  
  177.     }  
  178.     if (!found)  
  179.     {  
  180.         GetNodePath(T->right, Node, Path, found);  
  181.     }  
  182.     if (!found)  
  183.         Path.pop_back();  
  184.     else  
  185.         return;  
  186. }  
  187. BiNode* GetLastCommonNode(const vector<BiNode*> Path1, const vector<BiNode*> Path2)//获取两条路径的最后一个共同节点  
  188. {  </span
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值