二叉树的遍历(非递归算法)

二叉树的遍历是面试中比较常见的问题,而且一般不会考你用递归的方法来实现。面试前准备一下非递归的算法还是有必要的。

   

                                                                                             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_TREE_NODE> AUX_STACK_TREE;
typedef stack<TREE_NODE*> 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值