Chinaunix

标题: 二叉树的递归与非递归遍历 [打印本页]

作者: ypxing    时间: 2007-11-16 10:58
标题: 二叉树的递归与非递归遍历
看了版主converse写的二叉树的递归与非递归遍历

http://www.cppblog.com/converse/archive/2006/07/08/9577.html

其中, 版主写到:
"感觉其中后序遍历的非递归算法比较困难,想了很久最后的实现还是不够优雅"

俺也写了一个玩玩, 功能一样, 但是思路不一样, 呵呵


  1. #include <iostream>
  2. #include <stack>
  3. #include <cassert>
  4. using namespace std;

  5. struct node
  6. {
  7.   node* lchild;
  8.   node* rchild;
  9.   int key;
  10.   node(int data=0, node* left=NULL, node* right=NULL)
  11.   {
  12.     key = data;
  13.     lchild = left;
  14.     rchild = right;
  15.   }
  16. };

  17. class Tree
  18. {
  19.   
  20. public:
  21.   Tree()
  22.   {
  23.     root = NULL;
  24.   }
  25.   Tree(int array[], int size);
  26.   ~Tree();
  27.   void traverse();
  28.   void postTraverse();
  29.   void recur_postTraverse(node* cur);
  30.   void preTraverse();
  31.   void recur_preTraverse(node* cur);
  32.   void inTraverse();
  33.   void recur_inTraverse(node* cur);

  34. private:
  35.   Tree(const Tree& t);
  36.   Tree& operator=(const Tree& t);
  37.   node* createTree(int array[], int size);
  38.   void destroyTree(node* cur);
  39. private:
  40.   node* root;
  41.   
  42. };

  43. Tree::Tree(int array[], int size)
  44. {
  45.   if ((array==NULL)||(size<=0))
  46.     root = NULL;
  47.   else
  48.     root = createTree(array, size);
  49. }

  50. node* Tree::createTree(int array[], int size)
  51. {
  52.   if ((array==NULL)||(size<=0))
  53.     return NULL;
  54.   int mid=size/2;
  55.   node* cur=new node(array[mid]);
  56.   cur->lchild = createTree(array, mid);
  57.   cur->rchild = createTree(array+mid+1, size-mid-1);
  58.   return cur;
  59. }

  60. Tree::~Tree()
  61. {
  62.   destroyTree(root);
  63. }

  64. void Tree::destroyTree(node* cur)
  65. {
  66.   if (cur != NULL)
  67.   {
  68.     destroyTree(cur->lchild);
  69.     destroyTree(cur->rchild);
  70.     delete cur;
  71.   }
  72.   
  73. }


  74. //后序递归遍历
  75. void Tree::recur_postTraverse(node* cur)
  76. {
  77.   if (cur!=NULL)
  78.   {
  79.     recur_postTraverse(cur->lchild);
  80.     recur_postTraverse(cur->rchild);
  81.     cout << cur->key << " ";
  82.   }
  83. }

  84. //先序递归遍历
  85. void Tree::recur_preTraverse(node* cur)
  86. {
  87.   if (cur!=NULL)
  88.   {
  89.     cout << cur->key << " ";
  90.     recur_preTraverse(cur->lchild);
  91.     recur_preTraverse(cur->rchild);
  92.   }
  93. }

  94. //中序递归遍历
  95. void Tree::recur_inTraverse(node* cur)
  96. {
  97.   if (cur!=NULL)
  98.   {
  99.     recur_inTraverse(cur->lchild);
  100.     cout << cur->key << " ";
  101.     recur_inTraverse(cur->rchild);
  102.   }
  103. }

  104. //后序非递归遍历
  105. void Tree::postTraverse()
  106. {
  107.   stack<node*> treeStack;
  108.   node *pre, *cur;
  109.   cur = root;
  110.   pre = NULL;
  111.   
  112.   if (cur!=NULL)
  113.     treeStack.push(cur);
  114.   
  115.   while(!treeStack.empty())
  116.   {
  117.     cur = treeStack.top();
  118.     if (((cur->lchild==NULL)&&(cur->rchild==NULL))||             //没有孩子结点或者
  119.         ((pre!=NULL)&&((pre==cur->lchild)||(pre==cur->rchild)))) //孩子遍历过了
  120.     {
  121.       treeStack.pop();
  122.       cout << cur->key << " ";
  123.       pre = cur;
  124.     }
  125.     else
  126.     {
  127.       if (cur->rchild!=NULL)
  128.         treeStack.push(cur->rchild);
  129.       if (cur->lchild!=NULL)
  130.         treeStack.push(cur->lchild);
  131.     }
  132.    
  133.   }
  134.   
  135. }

  136. //中序非递归遍历
  137. void Tree::inTraverse()
  138. {
  139.   stack<node*> treeStack;
  140.   node *pre, *cur;
  141.   cur = root;
  142.   
  143.   if (cur!=NULL)
  144.     treeStack.push(cur);
  145.   
  146.   while(!treeStack.empty())
  147.   {
  148.     cur = treeStack.top();
  149.     treeStack.pop();
  150.     if (cur == NULL)
  151.       continue;
  152.     if ((cur->lchild==NULL)||                                   //没有左孩子或者
  153.         ((!treeStack.empty())&&(treeStack.top()==cur->rchild))) //右孩子已经入过栈
  154.       cout << cur->key << " ";
  155.     else
  156.     {
  157.       treeStack.push(cur->rchild);
  158.       treeStack.push(cur);
  159.       if (cur->lchild!=NULL)
  160.         treeStack.push(cur->lchild);
  161.     }
  162.    
  163.   }
  164. }

  165. //先序非递归遍历
  166. void Tree::preTraverse()
  167. {
  168.   stack<node*> treeStack;
  169.   node *pre, *cur;
  170.   cur = root;
  171.   
  172.   if (cur!=NULL)
  173.     treeStack.push(cur);
  174.   
  175.   while(!treeStack.empty())
  176.   {
  177.     cur = treeStack.top();
  178.     treeStack.pop();
  179.     cout << cur->key << " ";
  180.     if (cur->rchild!=NULL)
  181.       treeStack.push(cur->rchild);
  182.     if (cur->lchild!=NULL)
  183.       treeStack.push(cur->lchild);
  184.   }
  185. }


  186. void Tree::traverse()
  187. {
  188.   recur_preTraverse(root);
  189.   cout << endl;
  190.   preTraverse();
  191.   cout << endl << endl;

  192.   recur_inTraverse(root);
  193.   cout << endl;
  194.   inTraverse();
  195.   cout << endl << endl;
  196.   
  197.   recur_postTraverse(root);
  198.   cout << endl;
  199.   postTraverse();
  200.   cout << endl << endl;
  201. }

  202. int main(int argc, char* argv[])
  203. {
  204.   int array[] = {2, 4, 5, 6, 8, 10, 11, 13, 15, 17, 20};
  205.   Tree tr(array, sizeof(array)/sizeof(array[0]));
  206.   tr.traverse();
  207. }
复制代码

[ 本帖最后由 ypxing 于 2007-11-16 11:22 编辑 ]
作者: converse    时间: 2007-11-16 15:37
没时间好好看看了,做个标记先~~





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2