问题:对一个二叉搜索树进行前序遍历,打印出每个结点的值,但是不能使用递归。
解题:
(1)递归可以用迭代来替代
(2)了解递归的前序遍历中发生了什么:①打印出根节点(或子树根节点)的值;②对左子树进行前序遍历;③对右子树进行前序遍历。
递归隐式地使用了一个数据结构栈来存放调用栈上的数据。实际上,递归调用用于隐式地在栈上存储右子树的地址,因此左子树遍历完后,可以继续遍历右子树。每次打印 一个结点,并移动到它的左子树上,它的右子树会首先存放在一个栈上,当没有任何子树时,从一个递归调用中返回,也就是从栈上弹出一个右子树结点。这个过程一直持
续到栈空为止。
(3)代码实现(核心代码)
结点的存储结构:
struct Node { int data;//数据域 Node* left;//指向左孩子的指针 Node* right;//指向右孩子的指针 };
思路一:
与其分别实现左子树和右子树结点的情况,不如将两个结点全部压入栈。这里就要考虑入栈的顺序:将右结点先压入栈,然后是左结点。
void preorderTraversal1(){ stack<Node*> s; s.push(root); while (s.size() > 0){ Node* cur = s.top(); s.pop(); cout << cur->data << " "; Node* n = cur->right; if (n != NULL){ s.push(n); } n = cur->left; if (n != NULL){ s.push(n); } } cout << endl; }
思路二:
程序开始时先将根结点入栈,再弹出结点A栈打印。并将弹出栈的结点A的右结点入栈,并将A移动指向它的左节点。重复以上过程直到栈空。
void preorderTraversal2(){ stack<Node*> s; Node* tmp = root; s.push(tmp); while (s.size() > 0){ tmp = s.top(); s.pop(); while (tmp != NULL){ cout << tmp->data << " "; if (tmp->right != NULL){ s.push(tmp->right); } tmp = tmp->left; } } }
ps:并非全部原创,是阅读《程序员面试攻略》第三版的读书笔记。
时间: 2024-11-08 09:48:08