二叉树的三种遍历有递归版本,和迭代版本。本文介绍一种新的思路。
参考了 http://coolshell.cn/articles/9886.html
- 在许多应用中,我们还需要对遍历本身进行抽象。假如有一个求和的函数sum,我们希望它能应用于链表,数组,二叉树等等不同的数据结构。这时,我们可以抽象出迭代器(Iterator)的概念,通过迭代器把算法和数据结构解耦了,使得通用算法能应用于不同类型的数据结构。
以下给出了三种遍历的迭代器算法。
class Iterator {
public:
virtual TreeNode* next() = 0;
};
class PreOrderIterator : public Iterator {
public:
PreOrderIterator(TreeNode * root) {
if(root) s.push(root);
}
virtual TreeNode* next() {
TreeNode *top(nullptr);
if(!s.empty()) {
top = s.top();
s.pop();
if(top->right_child)
s.push(top->right_child);
if(top->left_child)
s.push(top->left_child);
}
return top;
}
private:
stack<TreeNode*> s;
};
class InOrderIterator : public Iterator {
public:
InOrderIterator(TreeNode * root) {
while(root) {
s.push(root);
root = root->left_child;
}
}
virtual TreeNode* next() {
TreeNode *top(nullptr);
TreeNode *cur(nullptr);
if(!s.empty()) {
top = cur = s.top();
s.pop();
cur = cur->right_child;
while(cur) {
s.push(cur);
cur = cur->left_child;
}
}
return top;
}
private:
stack<TreeNode*> s;
};
class PostOrderIterator : public Iterator {
public:
PostOrderIterator(TreeNode *root): pre(nullptr) {
while(root) {
s.push(root);
root = root->left_child;
}
}
virtual TreeNode* next() {
TreeNode *cur(nullptr);
while(cur || !s.empty()) {
while(cur) {
s.push(cur);
cur = cur->left_child;
}
cur = s.top(); s.pop();
if(nullptr == cur->right_child || pre == cur->right_child) {
//right_child is nullptr or already visited
pre = cur;
return cur;
}
else {
s.push(cur);
cur = cur->right_child;
}
}
return nullptr;
}
private:
TreeNode *pre; //previously visited node
stack<TreeNode*> s;
};
上述迭代器的使用方法如下:
PostOrderIterator iter(root);
TreeNode *node = iter.next();
while(node) {
cout << node->value << " ";
node = iter.next();
}
cout << endl;