二叉树的先序、中序、后序递归遍历和非递归遍历

文章转载自:http://blog.csdn.net/htyurencaotang/article/details/12379887

  1. #include "stdafx.h"  
  2. #include   
  3. using namespace std;  
  4.   
  5. const int MAXSIZE = 20; //定义栈空间大小为20  
  6.   
  7. struct BTNode  
  8. {  
  9.     char m_value;  
  10.     BTNode *m_left;  
  11.     BTNode *m_right;  
  12. };  
  13.   
  14. BTNode *stackArr[MAXSIZE] = {0};//用一个静态数组模拟栈  
  15. int nTop = -1;//初始状态下nTop=-1表示栈空  
  16.   
  17. //先序创建二叉树  
  18. void CreatBTree(BTNode *&root)  
  19. {     
  20.     char nValue = 0;  
  21.     cin >> nValue;  
  22.     if ('#' == nValue)  
  23.     {  
  24.        return;  
  25.     }  
  26.     else  
  27.     {  
  28.         root = new BTNode();  
  29.         root->m_value = nValue;  
  30.         CreatBTree(root->m_left);  
  31.         CreatBTree(root->m_right);  
  32.     }     
  33. }  
  34.   
  35. //先序遍历二叉树(递归)  
  36. void PreOrderTravse(BTNode *&pRoot)  
  37. {  
  38.     if (pRoot != NULL)  
  39.     {  
  40.         cout << pRoot->m_value << " ";  
  41.         PreOrderTravse(pRoot->m_left);         
  42.         PreOrderTravse(pRoot->m_right);  
  43.     }  
  44. }  
  45.   
  46. //中序遍历二叉树(递归)  
  47. void InOrderTravse(BTNode *&pRoot)  
  48. {  
  49.     if (pRoot != NULL)  
  50.     {  
  51.         InOrderTravse(pRoot->m_left);  
  52.         cout << pRoot->m_value << " ";  
  53.         InOrderTravse(pRoot->m_right);  
  54.     }  
  55. }  
  56.   
  57. //后序遍历二叉树(递归)  
  58. void PostOrderTravse(BTNode *&pRoot)  
  59. {  
  60.     if (pRoot != NULL)  
  61.     {  
  62.         PostOrderTravse(pRoot->m_left);        
  63.         PostOrderTravse(pRoot->m_right);  
  64.         cout << pRoot->m_value << " ";  
  65.     }  
  66. }  
  67.   
  68. //先序遍历二叉树(非递归)  
  69. void PreOrderNoReTravse(BTNode *pRoot)  
  70. {  
  71.     BTNode *pCur = pRoot;  
  72.     while (pCur != NULL || nTop != -1)//当前指针不空或栈不空  
  73.     {  
  74.         while (pCur != NULL)//当前指针不空  
  75.         {  
  76.             cout << pCur->m_value << " ";  
  77.             stackArr[++nTop] = pCur;//将当前指针入栈  
  78.             pCur = pCur->m_left;  
  79.         }  
  80.   
  81.         if (nTop != -1)//栈不空  
  82.         {  
  83.             BTNode *pTop = stackArr[nTop--];//获取栈顶指针且栈顶指针出栈           
  84.             pCur = pTop->m_right;  
  85.         }  
  86.     }  
  87. }  
  88.   
  89. //中序遍历二叉树(非递归)//递归转换为非递归:利用栈和while循环  
  90. void InOrderNoReTravse(BTNode *pRoot)  
  91. {  
  92.     BTNode *pCur = pRoot;  
  93.     while (pCur != NULL || nTop != -1)//当前指针不空或栈不空  
  94.     {  
  95.         while (pCur != NULL)//当前指针不空  
  96.         {             
  97.             stackArr[++nTop] = pCur;//将当前指针入栈  
  98.             pCur = pCur->m_left;  
  99.         }  
  100.   
  101.         if (nTop != -1)//栈不空  
  102.         {  
  103.             BTNode *pTop = stackArr[nTop--];//获取栈顶指针且栈顶指针出栈  
  104.             cout << pTop->m_value << " ";  
  105.             pCur = pTop->m_right;  
  106.         }  
  107.     }  
  108. }  
  109.   
  110. //后序遍历二叉树(非递归)  
  111. void PostOrderNoReTravse(BTNode *pRoot)  
  112. {     
  113.     BTNode *pCur = pRoot;  
  114.     BTNode *pTop = NULL;  
  115.     int nTag[MAXSIZE] = {0}; //标记数组标记每个元素的左右子树是否都已经被访问过了  
  116.     while (pCur != NULL || nTop != -1)//当前指针不空或栈不空  
  117.     {  
  118.         while (pCur != NULL)//当前指针不空  
  119.         {             
  120.             stackArr[++nTop] = pCur;//将当前指针入栈  
  121.             nTag[nTop] = 0;//表示第一次位于栈顶  
  122.             pCur = pCur->m_left;  
  123.         }  
  124.   
  125.         while (nTop != -1 && nTag[nTop] == 1)  
  126.         {//栈不空且栈顶指针指向的结点被标记为1即表示给结点的左右子树都已经被访问过了,第二次位于栈顶  
  127.             pTop = stackArr[nTop--];//获取栈顶指针且栈顶指针出栈  
  128.             cout << pTop->m_value << " ";  
  129.         }  
  130.   
  131.         if (nTop != -1)//栈不空  此时标记为0,意味着应该访问其右子树  
  132.         {                 
  133.             pTop = stackArr[nTop];//取到栈顶元素,注意此时不能出栈  
  134.             pCur = pTop->m_right;  
  135.             nTag[nTop] = 1;  
  136.         }  
  137.     }  
  138. }  
  139.   
  140. // 后序遍历二叉树(非递归)思想:  
  141. // 对于一棵树t,如果t非空,首先应该进入t的左子树访问,此时由于t的右子树及根结点尚未访问,  
  142. // 因此必须将t保存起来,放入栈中,以便访问完左子树后,从栈中取出t,进行其右子树及根结点的访问。  
  143. // 这里值得注意的是,当一个元素位于栈顶即将处理时,其左子树的访问一定已经完成,  
  144. // 如果其右子树尚未遍历,接下来应该进入其右子树的访问,而此时该栈顶元素是不能出栈的,  
  145. // 因为其根结点还未被访问;只有等到其右子树也访问完成后,该栈顶元素才能出栈,并输其根结点的值。  
  146. // 因此,在二叉树后序遍历的过程中,必须使用标记数组,其每个元素取值为0或1,  
  147. // 用于标识栈中每个元素的状态。当一个元素刚进栈时,其对应的tag值置0;当它第一次位于栈顶即将  
  148. // 被处理时,其tag值为0,意味着应该访问其右子树,于是将其右子树作为当前处理的对象,  
  149. // 此时该栈顶元素仍应该保留在栈中,并将其对应的tag值改为1;当其右子树访问完成后,  
  150. // 该元素又一次位于栈顶,而此时其tag值为1,意味着应该访问其根结点,并将其出栈。  
  151. // 在整个二叉树后序遍历的过程中,程序要做的工作始终分成两个部分:当前正在处理的树(子树)  
  152. // 和保存在栈中待处理的部分。只有这两部分的工作均完成后,程序方能结束。  
  153.   
  154. int _tmain(int argc, _TCHAR* argv[])  
  155. {  
  156.     BTNode *pRoot = NULL;  
  157.     CreatBTree(pRoot);  
  158.   
  159.     cout << "二叉树的先序、中序、后序遍历(递归)分别为:" << endl;  
  160.     PreOrderTravse(pRoot);//先序遍历递归  
  161.     cout << endl;  
  162.     InOrderTravse(pRoot);//中序遍历递归  
  163.     cout << endl;  
  164.     PostOrderTravse(pRoot);//后序遍历递归  
  165.     cout << endl;  
  166.   
  167.     cout << "二叉树的先序、中序、后序遍历(非递归)分别为:" << endl;  
  168.     PreOrderNoReTravse(pRoot);//先序遍历非递归  
  169.     cout << endl;  
  170.     InOrderNoReTravse(pRoot);//中序遍历非递归  
  171.     cout << endl;  
  172.     PostOrderNoReTravse(pRoot);//中序遍历非递归  
  173.     cout << endl;  
  174.   
  175.     system("pause");  
  176.     return 0;  
  177. }  

运行结果:

二叉树的先序、中序、后序递归遍历和非递归遍历_第1张图片


你可能感兴趣的:(二叉树,二叉树遍历,递归,非递归)