数据结构 《22》---- 二叉树三种遍历的迭代器算法

二叉树的三种遍历有递归版本,和迭代版本。本文介绍一种新的思路。
参考了 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;


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值