树的递归实现方式很简单,下面介绍三种遍历的非递归实现。
树的遍历有个特点,那就是在处理具体问题时,绝大多数情况下是在当前循环、或函数(或是子树)的根节点来处理的,能够注意到当前根节点是如何从上个根节点得来是关键。
1.先序遍历
注意栈先进后出,先压右节点。
void preOrder(node *root) {
stack<node*> sk;
sk.push(root);
while (!sk.empty()) {
node *cur = sk.top(); // 栈顶元素是当前的结点
sk.pop(); // 弹出栈顶元素
cout << cur->v << " "; // 输出
if (cur->rson) sk.push(cur->rson);
if (cur->lson) sk.push(cur->lson);
}
}
2.中序遍历
//m1
void Inorder(node *root) {
stack<node*> sk;
while (!sk.empty() || root != NULL) {
if (root == NULL) { // 左为空
node *cur = sk.top();
sk.pop();
cout << cur->v << " "; // 左子树遍历完 输出当前
root = cur->rson;// 遍历右子树
} else {
sk.push(root);
root = root->lson; //先遍历左子树
}
}
}
//m2 迭代法确定先后顺序
int kthSmallest(TreeNode* root, int k) {
stack<TreeNode*> stack;
while (root || stack.size() > 0) {
while (root) {
stack.push(root);
root = root->left;
}
root = stack.top();
stack.pop();
k--;
if (k == 0) {
return root->val;
}
root = root->right;
}
return 0;
}
3. 后序遍历:创建两个空栈,一个栈保存结点元素,一个栈保存输出的答案 根右左到左右根
void posOrder(node *root) {
stack<node*> sk; // 保存结点元素
stack<node*> res; // 保存输出的元素
sk.push(root);
while (!sk.empty()) { // 根右左
node *cur = sk.top();
sk.pop();
res.push(cur);
if(cur->lson) sk.push(cur->lson);
if(cur->rson) sk.push(cur->rson);
}
while (!res.empty()) { // 左右根
cout << res.top()->v << " ";
res.pop();
}
}