编程练习-二叉树(父节点、非递归、O(0)空间)

1、一个有父节点的二叉树,不用递归和堆栈,遍历二叉树

思路是这样的,如果采用先序遍历的方法,首先遍历根节点,然后沿左子树下降,直到遍历到最左节点,此时返回最左节点的父节点,如果父节点的右子树非空,采用相同的方式遍历右子树,如果右子树已经比遍历完毕(通过parent->right == current来判断),那么向上回溯,如果当前节点一直来自于右子树,那么继续回溯,直到根节点或者节点不是右子树为止,如果当前节点不为空,那么继续回溯,在回溯的过程中判断回溯的节点的右子树是否为空,如果不为空,则遍历右子树,知道当前节点为空为止,也就是当前节点为根节点的父节点为止。

#include <stdio.h>
template<typename T>
class VisitFun {
 public:
  virtual void operator()(const T& value) const = 0;
  virtual void operator()(const T& value, const T& parent_value) const = 0;
};
class VisitFunInt : public VisitFun<int> {
 public:
  virtual void operator()(const int& value) const {
    printf("%d ", value);
  }
  virtual void operator()(const int& value, const int& parent_value) const {
    printf("%d:%d ", value, parent_value);
  }
};
template<typename T>
class BinaryTree {
 private:
  class TreeNode {
   public:
    TreeNode(const T& value, TreeNode* parent) : data_(value), left_(NULL), right_(NULL), parent_(parent) {}
    T data_;
    TreeNode* left_;
    TreeNode* right_;
    TreeNode* parent_;
  };
 public:
  BinaryTree() : root_(NULL) {}
  void Insert(const T& value) {
    Insert(value, root_, NULL);
  }
  void InOrderVisit(const VisitFun<T>& visit_fun) {
    TreeNode* current = VisitLeftMost(root_, visit_fun);
    while (current) {
      current = VisitBack(current, visit_fun);
    }
  }
  void InOrderVisitRecursive(const VisitFun<T>& visit_fun) {
    InOrderVisitRecursive(root_, visit_fun);
  }  
 private:
  void Insert(const T& value, TreeNode*& current, TreeNode* parent) {
    if (current == NULL) {
      current = new TreeNode(value, parent);
    } else {
      if (value >= current->data_) {
        Insert(value, current->right_, current);
      } else {
        Insert(value, current->left_, current);
      }
    }
  }
  TreeNode* VisitLeftMost(TreeNode* current, const VisitFun<T>& visit_fun) {
    TreeNode* parent = NULL;
    while(current) {
      visit_fun(current->data_);
      parent = current;
      current = current->left_;
    }
    return parent;
  }
  TreeNode* VisitBack(TreeNode* current, const VisitFun<T>& visit_fun) {
    TreeNode* parent;
    if (current->right_) {
      return VisitLeftMost(current->right_, visit_fun);
    }
    parent = current->parent_;
    while (parent && parent->right_ == current) {
      current = parent;
      parent = current->parent_;
    }
    return parent;
  }
  void InOrderVisitRecursive(TreeNode* current, const VisitFun<T>& visit_fun) {
   if (current) {
     if (current->parent_) {
       visit_fun(current->data_, current->parent_->data_);
     } else {
       T tmp;
       visit_fun(current->data_, tmp);
     }     
   }
   if (current->left_) {
     InOrderVisitRecursive(current->left_, visit_fun);
   }
   if (current->right_) {
     InOrderVisitRecursive(current->right_, visit_fun);
   }
 }
  TreeNode* root_;
};

int main(int argc, char** argv) {
  int array[] = {3, 5, 2, 4, 7};
  int array_size = sizeof(array) / sizeof(int);
  VisitFunInt print_int;
  BinaryTree<int> binary_tree;
  for (int i = 0; i < array_size; ++i) {
    binary_tree.Insert(array[i]);
  }
  //  binary_tree.InOrderVisitRecursive(print_int);
  binary_tree.InOrderVisit(print_int);
}

 参考:

http://www.winzp.org/blog/archives/406

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值