二叉树的4种历遍
先序遍历
遍历过程:
1,先访问根节点
2,先序遍历左子树
2,先序遍历右子树
递归实现:
//先序遍历
void preOrderTraversal(binTree bt){
if(NULL != bt){//空时结束
printf("%d ",bt->data);
preOrderTraversal(bt->left);//左子树递归
preOrderTraversal(bt->right);//右子树递归
}
}
堆栈实现:
//先序遍历
void preOrderTraversal(binTree bt){
binTree t=bt;
stack s = creatStack(MaxSize);
while(t || !isEmpty(s)){
while(t){//一直向左并把节点压入堆栈
printf("%d ",t->data);//打印
push(s,t);
t=t->left;
}
if(!isEmpty(s)){
t=pop(s);//弹出结点
t=t->right;//转向右子树
}
}
}
遍历顺序为:a(b,d,f,e)(c,g,h,i)(根节点)(左子树)(右子树)
中序遍历
遍历过程:
1,中序遍历左子树
2,访问根节点
3,中序遍历右子树
递归实现:
//中序遍历
void inOrderTraversal(binTree bt){
if(NULL != bt){//空时结束
inOrderTraversal(bt->left);//左子树递归
printf("%d ",bt->data);
inOrderTraversal(bt->right);//右子树递归
}
}
堆栈实现:
//中序遍历
void inOrderTraversal(binTree bt){
binTree t=bt;
stack s = creatStack(MaxSize);
while(t || !isEmpty(s)){
while(t){//一直向左并把节点压入堆栈
push(s,t);
t=t->left;
}
if(!isEmpty(s)){
t=pop(s);//弹出结点
printf("%d ",t->data);//打印
t=t->right;//转向右子树
}
}
}
遍历顺序为:(d,b,e,f)a(g,h,c,i)(左)(根)(右)
后序遍历
遍历过程:
1,后序遍历左子树
2,后序遍历右子树
3,访问根节点
递归实现:
//后序遍历
void postOrderTraversal(binTree bt){
if(NULL != bt){//空时结束
inOrderTraversal(bt->left);//左子树递归
inOrderTraversal(bt->right);//右子树递归
printf("%d ",bt->data);
}
}
遍历顺序:(d,e,f,b)(h,g,i,c)a(左)(右)(根)
先序,中序和后续遍历结语
先序遍历,中序遍历和后续遍历:遍历所经历的结点路线是一样的,只是printf的时机不同。
层序遍历
1,从队列中取出一个元素
2,访问元素结点
3,若元素所指左右非空,就将左右结点放入队列
队列实现:
//层序
void levelOrderTraversal(binTree bt ){
binTree t;
if(!bt) return;
queue q = creatQueue(MaxSize);//构造队列
addq(q,bt);
while(!isEmpty(q)){
t=deleteq(q);//抛出一个结点
printf("%d ",t->data);
if(t->left) addq(q,t->left);
if(t->right) addq(q,t->right);
}
}
遍历顺序:
结语
树的遍历就是将树型变成线型输出。只不过访问的顺序不同。