二叉树深度遍历的几种写法
二叉树的结构:
struct treeNode{
int val;
treeNode* left;
treeNode* right;
treeNode(int x):val(x),left(NULL),right(NULL){}
};
最简单的是递归方式写出,这种效率比较差,但是实现方便
这里写了3种非递归方式实现的方法:
1.
该方法每次利用一个栈。
每一次保存遍历节点的右节点。
对于每一个节点A,节点A先出战,然后节点A的右节点先进栈,左节点再进栈。
这样每次循环,总是根节点在前,然后每一次左点出战,先不断向左遍历。
左方出栈完成后,右节点再出栈。
保证了根-左-右的出栈顺序。
void preOrder1(treeNode* P){
if(p==NULL) return;
std::vector<treeNode*> stack;
stack.push_back(p);
while(stack.size()>0){
treeNode* t=*(stack.end()-1);
printf("%d\n",t->val);
stack.pop_back();
if(t->right!=NULL){
stack.push_back(t->right);
}
if(t->left!=NULL){
stack.push_back(t->left);
}
}
}
2.
该方法也是利用了一个栈。
每一次先顺序遍历完以节点p为根节点树最左边的节点。
这保证栈顶结点必然是没有左孩子的。
在将栈顶节点出栈。
进入栈顶节点的右节点进栈(如果不为空)
再以该节点为根,顺序向左进栈。
这样保证节点都是 根-左-右 顺序进栈。
void preOrder2(treeNode* p){
std::vector<treeNode*> stack;
while(p!=NULL){
stack.push_back(p);
printf("%d\n",p->val);
if(p->left!=NULL){
p=p->left;
}
}
while(stack.size()>0){
treeNode* tail=*(stack.end()-1);
stack.pop_back();
if(tail->right!=NULL){
p=tail->right;
}
while(p!=NULL){
printf("%d\n",p->val);
stack.push_back(p);
if(p->left!=NULL){
p=p->left;
}
}
}
}
3.
该方法对二叉树每个序列都深度遍历到底,这样方便计算每个节点的高度。
者需要每一次深度遍历后,打印栈的长度即可。
void preOrder(treeNode* p){
std::vector<treeNode*> stack;
int insert=0;
while(1){
if(insert==0){
while(p!=NULL){
stack.push_back(p);
printf("%d\n",p->val);
if(p->left!=NULL){
p=p->left;
}else if(p->right!=NULL){
p=p->right;
}else{
break;
}
}
}
if(stack.size()<2)
break;
treeNode* tail1=*(stack.end()-1);
stack.pop_back();
treeNode* tail2=*(stack.end()-1);
if(tail1==tail2->left){
p=tail2->right;
insert=0;
}else{
insert=1;
}
}
}