二叉树的遍历:前序遍历,中序遍历,后序遍历,每种遍历又分为递归和非递归算法,递归遍历较为简单,容易理解;非递归需要用到栈,相对麻烦一些。
typedef struct node{
int data;
struct * lchild,*rchild;
}*BiTree, BiTNode
首先是前序遍历:
递归算法:
void PreOrderTravers( BiTree tree){
printf("%d",tree->data);
PreOrderTravers( tree->lchild);
PreOrderTravers(tree->rchild);
}
非递归算法:
void PreOrderTravers2( BiTree tree){
stack<*BiTree> s;
BiTNode *p =tree;
while( p!=NULL || !s.empty()){
while( p!=NULL){
printf("%d",p->data);
s.push(p);
p=p->lchild
}
if(!s.empty()){
p=s.top();
s.pop();
p=p->rchild;
}
}
}
中序遍历算法:
递归算法:
InOrderTravers(BiTree tree){
if( tree ){
InOrderTravers( tree->lchild);
printf( "%d",tree->data);
InOr derTravers(tree->rchild);
}
}
非递归算法:
InOrderTravers2(BiTree tree){
BiTNode *p =tree;
stack<*BiTNode> s;
while( p!=NULL ||! s.empty()){
while( p!=NULL){
s.push(p);
p=p->lchild;
}
if( !s.empty()){
p=s.top();
s.pop();
printf("%d",p->data);
p=p->rchild;
}
}
}
后序遍历:
递归算法:
PostOrderTravers( BiTree tree){
if(tree){
PostOrderTravers( tree->lchild);
PostOrderTravers(tree->rchild);
printf("%d",tree->data);
}
}
非递归算法:
主要思路:利用栈的存储特性,如果要满足 访问顺序为 左子树->右子树->根结点,则入栈顺序为 根结点->右子树->左子树;
如果某个结点没有孩子结点或者该孩子结点已经被访问过,则访问该节点。
PostOrderTravers2( BiTree tree){
stack<BiTNode *> s;
s.push(tree);
BiTNode * cur=NULL: //现在结点
BiTnode * pre=NULL; //已经访问过的结点
while( !s.empty()){
cur=s.top()
if ((cur->lchild==NULL&&cur->rchild==NULL) || (pre!=NULL&&(cur->lchild==pre || cur->rchild ==pre)) ){
//如果该结点没有子节点或者该节点右子结点,但是子结点已经被访问过,则访问该节点。
printf("%d",cur->data);
pre=cur;
s.pop()
}
else{
if(cur->rchild){
s.push(cur->rchild);
}
if(cur->lchild){
s.push(cur->lchild);
}
}
}
}