二叉树的三种遍历有递归版本,和迭代版本。本文介绍一种新的思路。
参考了 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;
数据结构 《22》---- 二叉树三种遍历的迭代器算法
时间: 2024-10-11 17:54:01