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);
}
参考: