常用的一些数据结构操作的实现,记录下来,便于以后查阅
二叉树先序遍历
void PreOrder(BitTree *T){
BitTree *p;
p=T;
stack<BitTree *> s;
while(!s.empty()||p){
if(p){
s.push(p);
cout<<p->val<<endl;//先序遍历
p=p->left;
}
else{
p=s.top();
s.pop();//这里先获得栈中顶部元素,然后pop顶部元素
p=p->right;
}
}
}
二叉树中序遍历
void InOrder(BitTree *T){
BitTree *p;
p=T;
stack<BitTree *> s;
while(!s.empty()||p){
if(p){
s.push(p);
p=p->left;
}
else{
p=s.top();
cout<<p->val<<endl;//与先序遍历相比的区别在于访问节点顺序不同,中序遍历要先访问左节点
s.pop();
p=p->right;
}
}
}
二叉树后序遍历
后序遍历要稍微复杂一些,涉及到右子树是否被访问过的问题,因为只有右孩子访问了,才能访问当前节点,否则不能将当前节点pop出栈
void InOrder(BitTree *T){
BitTree *p;
p=T;
BitTree *preNode=NULL;
stack<BitTree *> s;
while(!s.empty()||p){
while(p){
s.push(p);
p=p->left;
}
p=s.top();
if(p->right==NULL||p->right==preNode)
s.pop();
cout<<p->val<<endl;
preNode=p;
p=NULL;
}
else{
p=p->right;
}
}
}
还有一种双栈法比较好实现,就是将后序遍历过程压入到另一个栈中,然后再遍历栈空间
void PostOrder(BiTree *T) // 后序遍历的非递归 双栈法
{
stack<BiTree *> s1 , s2;
BiTree *curr ; // 指向当前要检查的节点
if(T)
s1.push(T);
while(!s1.empty()) // 栈空时结束
{
curr = s1.top();
s1.pop();
s2.push(curr);
if(curr->left)
s1.push(curr->left);
if(curr->right)
s1.push(curr->right);
}
while(!s2.empty())
{
cout<<s2.top()->val<<endl;
s2.pop();
}
}