树的递归实现方式很简单,下面介绍三种遍历的非递归实现。
树的遍历有个特点,那就是在处理具体问题时,绝大多数情况下是在当前循环、或函数(或是子树)的根节点来处理的,能够注意到当前根节点是如何从上个根节点得来是关键。
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();}
}