二叉树遍历方法总结

1,   二叉树结构

struct TreeNode

{

         int val;

         TreeNode* left;

         TreeNode* right;

         TreeNode(int x) : val(x), left(NULL), right(NULL) {}

};

 

 

2,   遍历方法

class BinaryTree

{

public:

         //二叉树的遍历

         //递归遍历

         //先序遍历

         void preOrderTraversal( TreeNode* root )

         {

                   if(root)

                   {

                            cout << root->val << " ";                //visit()

                            preOrderTraversal( root->left );

                            preOrderTraversal( root->right );

                   }

         }

         //中序遍历

         void inOrderTraverval( TreeNode* root )

         {

                   if( root )

                   {

                            inOrderTraverval( root->left );

                            cout << root->val << " ";                //visit()

                            inOrderTraverval( root->right );

                   }

         }

         //后序遍历

         void postOrderTraverval( TreeNode* root )

         {

                   if(root)

                   {

                            postOrderTraverval(root->left);

                            postOrderTraverval(root->right);

                            cout << root->val << " ";                //visit()

                   }

         }

 

         //循环迭代法遍历二叉树

         //先序遍历

         void visitAlongLeftBranch(TreeNode* root, stack<TreeNode*> &S)

         {

                   while(root)

                   {

                            cout << root->val << " ";                //visit()

                            S.push(root->right);               //右孩子入栈暂存(可优化,通过判断,避免空的右孩子入栈)

                            root = root->left;           //往左分支深入一层

                   }

         }

         void preOrderVisit(TreeNode* root)

         {

                   stack<TreeNode*> S;            //辅助栈

                   while(true)

                   {

                            visitAlongLeftBranch(root, S);                 //从当前节点出发,逐批访问

                            if(S.empty()) break;               //直到栈空为止

                            root = S.top();               //得到下一批的起点

                            S.pop();

                   }

         }

 

         //中序遍历1

         void goAlongLeftBranch(TreeNode* root, stack<TreeNode *> &S)

         {

                   //当前节点入栈后随即向左分支深入一层,迭代到无左孩子为止

                   while(root)  { S.push(root);  root = root->left; }             

         }

 

         void inOrderVisit1(TreeNode * root)

         {

                   stack<TreeNode *> S;

                   while(true)

                   {

                            goAlongLeftBranch(root, S);  //从当前节点出发,逐批入栈

                            if(S.empty()) break;               //直到所有节点处理完毕

                            root = S.top();               //弹出栈顶元素并访问

                            S.pop();

                            cout << root->val << " ";                //visit()

                            root = root->right;                  //转向右孩子

                   }

         }

 

         //中序遍历2

         void inOrderVisit2(TreeNode * root)

         {

                   stack<TreeNode *> S;

                   while(true)

                   {

                            if(root)

                            {

                                     S.push(root);

                                     root = root->left;

                            }

                            else if(!S.empty())

                            {

                                     root = S.top();

                                     S.pop();

                                     cout << root->val << " ";

                                     root = root->right;

                            }

                            else

                                     break;

                   }

         }

 

         //后续遍历

         void postOrderVisit(TreeNode* root)

         {

                   stack<TreeNode*> S;

                   TreeNode *ptr = NULL, *pre = NULL; //pre指向已访问过的最后一个节点

                   if(root) S.push(root);             //根节点进栈

 

                   while(!S.empty())

                   {

                            ptr = S.top();                 //获取栈顶元素

                            /*

                            如果当前节点有左子树,且左子树节点不是刚被访问的节点;如果当前节点有右子树,且右

                            子树节点不是刚被访问的节点,表明栈顶元素指向的树节点未被访问到,且左子树右子树均

                            未被访问到,将左子树节点入栈,深入一层。

                            */

                           

                            if(ptr->left && pre != ptr->left && !(ptr->right && pre == ptr->right))

                                     S.push(ptr->left);

                            //如果栈顶元素的右子树存在,且不是刚被访问的节点,则将右子树节点入栈,深入一层。

                            else if(ptr->right && pre != ptr->right)

                                     S.push(ptr->right);

                            //如果栈顶元素的左右子树均被访问过,则访问栈顶元素,将栈顶元素退栈。并更新pre

                            else

                            {

                                     cout << ptr->val << " ";                  //visit()

                                     S.pop();

                                     pre = ptr;

                            }

                   }

         }

};

 

posted @ 2015-06-11 16:04  imKirin  阅读(295)  评论(0编辑  收藏  举报