首页 > 代码库 > 二叉树非递归访问
二叉树非递归访问
二叉树非递归访问,借助一个栈,来模拟递归调用过程。
?
1 2 3 4 5 6 | struct TreeNode { char val; TreeNode *left; TreeNode *right; TreeNode( int x) : val(x), left(NULL), right(NULL) {} }; |
1. 先序遍历
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | void PreOrder(TreeNode *root) { if (root == NULL) return ; stack<TreeNode*> s; s.push(root); while (!s.empty()) { TreeNode *node = s.top(); s.pop(); if (node->right != NULL) s.push(node->right); if (node ->left != NULL) s.push(node->left); cout << node->val << " " ; } } |
2. 中序遍历
中序遍历,有一个很有意思的规律,从左子树返回,就要访问根节点。
所以,记录一下当前访问状态是下降(访问左子树)状态,还是从左子树返回状态。
从左子树返回后,要访问根节点,同时,如果根节点有右子树,要访问右子树。
右子树访问结束后,整棵访问完的子树又相当于一个左子树。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | void InOrder(TreeNode *root) { if (root == NULL) return ; stack<TreeNode*> s; s.push(root); TreeNode *prev = NULL; while (!s.empty()) { TreeNode *curr = s.top(); //当前是下降过程 if (!prev || prev->left == curr || prev->right == curr) { if (curr->left != NULL) s.push(curr->left); } else // 从左子树返回 { s.pop(); cout << curr->val << " " ; if (curr->right != NULL) s.push(curr->right); } prev = curr; } } |
3. 后序遍历
后序遍历,要在第二次返回的时候访问根节点。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | void PostOrder(TreeNode *root) { if (root == NULL) return ; stack<TreeNode*> s; s.push(root); TreeNode *prev = NULL; TreeNode *curr = NULL; while (!s.empty()) { curr = s.top(); if (!prev || prev->left == curr || prev->right == curr) { if (curr->left != NULL) s.push(curr->left); else if (curr->right != NULL) s.push(curr->right); } else if (curr->left == prev) //左子树返回 { if (curr->right != NULL) s.push(curr->right); } else //从右子树返回 或 无右子树 { s.pop(); cout << curr->val << " " ; } prev = curr; } } |
比较简单的一种后序访问就是采用双栈策略。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | void PostOrder(TreeNode *root) { if (root == NULL) return ; stack<TreeNode*> s; stack<TreeNode*> result; TreeNode *curr = NULL; s.push(root); while (!s.empty()) { curr = s.top(); s.pop(); result.push(curr); if (curr->left != NULL) s.push(curr->left); if (curr->right != NULL) s.push(curr->right); } while (!result.empty()) { curr = result.top(); result.pop(); cout << curr->val << " " ; } } |
按照后序遍历的顺序,将最后要访问的结点压入result栈的栈底。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。