二叉树的遍历是面试中比较常见的问题,而且一般不会考你用递归的方法来实现。面试前准备一下非递归的算法还是有必要的。
A
B E
C D F G
输出:
Pre-order :
ABCDEFG
Middle-order:
CBDAFEG
Post-Order:
CDBFGEA
Pseudo:
Pre-order:
Visit(cur_code); //user defined function
WalkThrough(left_child);
WalkThrought(right_child);
Middle-order:
WalkThrough(left_child);
Visit(cur_node);
WalkThrough
Post-order:
WalkThrough(left_child);
WalThrough(right_child);
Visit(cur_code);
在非递归算法中是用到STACK的,这里我们使用stl中的stack。
下面是一些必要的类型定义。
struct TREE_NODE{
TREE_NODE* left;
TREE_NODE* right;
char data;
};
enum TAG{
LEFT = 0,
RIGHT = 1
};
struct AUX_TREE_NODE{
TREE_NODE* p_tree_node;
TAG tag;
};
typedef void (__stdcall *VISIT)(TREE_NODE*);
typedef stack
AUX_STACK_TREE;
typedef stack STACK_NODE;
static char symbol_count = 0;
void __stdcall print_c(TREE_NODE* p){
printf("%c/n",p->data);
}
void __stdcall destroy_c(TREE_NODE* p){
delete p;
}
为了产生上图的树结构,我们调用了下面这个函数:
void CreateTree(TREE_NODE* parent, int level){
parent->data = 'A' + symbol_count;
symbol_count++;
if(level >= 2 ){
parent->left = parent->right = 0;
return;
}
parent->left = new TREE_NODE;
parent->right = new TREE_NODE;
CreateTree(parent->left,level + 1);
CreateTree(parent->right,level + 1);
}
下面是三种不同非递归遍历函数
void pre_order(TREE_NODE* root,VISIT visit){
TREE_NODE* p;
STACK_NODE s_node;
s_node.push(root);
while(!s_node.empty()){
p = s_node.top();
s_node.pop();
if(p){
s_node.push(p->right);
s_node.push(p->left);
visit(p);
}
}
}
void middle_order(TREE_NODE* root,VISIT visit){
TREE_NODE* p = root;
STACK_NODE s_node;
s_node.push(root);
while(!s_node.empty()){
if(p){
s_node.push(p->left);
p = p->left;
}else{
p = s_node.top();
s_node.pop();
if(p){
TREE_NODE* p_temp = p->right;
visit(p);
p = p_temp;
s_node.push(p);
}
}
}
}
void post_order(TREE_NODE* root,VISIT visit){
AUX_STACK_TREE aux_stack_tree;
AUX_TREE_NODE aux_tree_node;
aux_tree_node.p_tree_node = root;
aux_tree_node.tag = LEFT;
aux_stack_tree.push(aux_tree_node);
TREE_NODE* p = root->left;
while(!aux_stack_tree.empty()){
while(p){
aux_tree_node.p_tree_node = p;
aux_tree_node.tag = LEFT;
aux_stack_tree.push(aux_tree_node);
p = p->left;
}
AUX_TREE_NODE* top_node;
while(!aux_stack_tree.empty() && (top_node = &(aux_stack_tree.top()), top_node->tag == RIGHT)){
visit(top_node->p_tree_node);
aux_stack_tree.pop();
}
if(!aux_stack_tree.empty()){
top_node = &(aux_stack_tree.top());
top_node->tag = RIGHT;
p = top_node->p_tree_node->right;
}
}
}
最后是测试代码
int main(int argc, char* argv[])
{
TREE_NODE* root = new TREE_NODE;
symbol_count = 0;
CreateTree(root,0);
printf("pre_oder/n");
pre_order(root,print_c);
printf("middle_oder/n");
middle_order(root,print_c);
printf("post_oder/n");
post_order(root,print_c);
pre_order(root,destroy_c);//释放空间
return 0;
}