递归时间、空间效率低、这里使用栈改为非递归。
前序遍历:
1.根节点入栈,
2.栈顶元素出栈,访问
3.该元素的右儿子入栈
4.该元素的左二子入栈
重复234直到栈空
中序遍历
区分两种情况(图)
1.用原有的Node类构造一个带有入栈次数的StNode
2.根节点入栈
3.栈顶元素出栈,如果是第一次,自己入栈,左儿子入栈;如果是第二次,访问,右儿子入栈。
4.重复3直到栈空
中序遍历
和中序类似,区分三种情况
1.用原有的Node类构造一个带有入栈次数的StNode
2.根节点入栈
3.栈顶元素出栈,如果是第一次,自己入栈,左儿子入栈;如果是第二次,自己入栈,右儿子入栈。如果是第三次,访问。
4.重复3直到栈空
代码
构造StNode
struct Node{//二叉树的结点类
Node*left,*right;
Type data;
Node():left(NULL),right(NULL){}
//参数化列表,内置结构体,结构体也可以有函数,不同之处:结构体定义中默认情况下的成员是public,而类定义中的默认情况下的成员是private的。
Node(Type item,Node *L=NULL,Node *R=NULL):data(item),left(L),right(R){}
};
struct StNode{
Node*node;
int TimesPop;
StNode(Node*N=NULL):node(N),TimesPop(0){}//struct构造struct
};
非递归遍历
void preOrder(){
stack<Node*>s;
Node *current;
cout<<"前序遍历:";
s.push(root);
while (!s.empty()) {
current = s.top();
s.pop();
cout<<current->data;
if (current->right!=NULL) {
s.push(current->right);
}
if (current->left!=NULL) {
s.push(current->left);
}
}
}
void midOrder(){
stack<StNode>s;
StNode current(root);
cout<<"中序遍历:";
s.push(current);
while (!s.empty()) {
current=s.top();
s.pop();
if(++current->TimesPop==1){
s.push(current);
if(current.node->left!=NULL)
s.push(StNode(current.node->left));//这个神仙操作,先求node,再构造回去,绕一圈
}
else{
cout<<current.node->data;
if(current.node->right!=NULL)
s.push(Stnode(current.node->right));
}
}
}
void postOrder() {
stack<StNode>s;
StNode current(root);
cout<<"后序遍历:";
s.push(current);
while (!s.empty()) {
current=s.top();
s.pop();
if(++current->TimesPop==1){
s.push(current);
if(current.node->left!=NULL)
s.push(StNode(current.node->left));//这个神仙操作,先求node,再构造回去,绕一圈
}
else if(++current->TimesPop==2){
s.push(current);
if(current.node->right!=NULL)
s.push(StNode(current.node->right));//这个神仙操作,先求node,再构造回去,绕一圈
}
else cout<<current.node->data;
}
}
对比递归遍历
void preOrder()const{
if(root!=NULL){
cout<<"\n先序遍历:";//\n加在”“里面也可以换行
preOrder(root);
}
}
void midOrder()const{
if(root!=NULL){
cout<<"\n中序遍历:";
midOrder(root);
}
}
void postOrder()const{
if(root!=NULL){
cout<<"\n后序遍历:";
postOrder(root);
}
}
具体解释
1.前序遍历
2.中序遍历
3.后序遍历