基本概念
二叉树的遍历 :指按某条搜索路径访问树中每个结点,使得每个结点均被访问一次, 而且仅被访问一次。
中序遍历:按照 左-根-右 的次序遍历。
图例
中序遍历序列:8 4 9 2 10 5 1 6 3 7
代码
结构体定义和构建二叉树的方法与先序遍历的一样(注意:这里构建中序遍历的二叉树仍按照先序的方法去构造二叉树)传送门:二叉树的先序遍历-Doris-510
递归遍历
//递归法遍历
void inorder(BiTree T){
if(T){//这里不加非空判断,不然遇到叶子结点后就不能递归下去了
inorder(T->lchild);//遍历左子树
cout<<T->val<<" ";//遍历根结点
inorder(T->rchild);//遍历右子树
}
}
非递归遍历
//非递归法遍历
void inorder1(BiTree T){
if(!T) return;
stack<BiTNode *> st;//初始化栈
BiTNode *p=T;//用一个p指针来遍历
while(p||!st.empty()){//循环条件:当前结点不为空或者栈不为空(重要!!!)
if(p){//若当前结点不为空
st.push(p);//当前结点进栈
p=p->lchild ;//访问左子树结点
}
else{//当前结点为空,说明左子树遍历完毕
p=st.top();//取出栈顶元素
st.pop();//弹出栈顶元素
cout<<p->val <<" ";//访问根结点
p=p->rchild ;//访问右子树节点
}
}
}
全部代码
#include<bits/stdc++.h>
using namespace std;
typedef struct BiTNode{
int val;//根结点的值
struct BiTNode *lchild,*rchild;//左孩子指针 右孩子指针
}BiTNode,*BiTree;
//二叉树构造函数
BiTree createTree(){
int val;
cin>>val;
if(val==-1) return NULL;//为叶子结点添加'-1'以唯一确定一棵二叉树
BiTNode *T=(BiTNode *)malloc(sizeof(BiTNode));
T->val =val;
T->lchild =createTree();
T->rchild =createTree();
}
//递归法遍历
void inorder(BiTree T){
if(T){//这里不加非空判断,不然遇到叶子结点后就不能递归下去了
inorder(T->lchild);//遍历左子树
cout<<T->val<<" ";//遍历根结点
inorder(T->rchild);//遍历右子树
}
}
//非递归法遍历
void inorder1(BiTree T){
if(!T) return;
stack<BiTNode *> st;//初始化栈
BiTNode *p=T;//用一个p指针来遍历
while(p||!st.empty()){//循环条件:当前结点不为空或者栈不为空(重要!!!)
if(p){//若当前结点不为空
st.push(p);//当前结点进栈
p=p->lchild ;//访问左子树结点
}
else{//当前结点为空,说明左子树遍历完毕
p=st.top();//取出栈顶元素
st.pop();//弹出栈顶元素
cout<<p->val <<" ";//访问根结点
p=p->rchild ;//访问右子树节点
}
}
}
int main(){
BiTree T=createTree();
cout<<"递归遍历结果:"<<endl;
inorder(T);
cout<<endl;
cout<<"非递归遍历结果:"<<endl;
inorder1(T);
return 0;
}
//二叉树中序遍历:1 2 4 8 -1 -1 9 -1 -1 5 10 -1 -1 -1 3 6 -1 -1 7 -1 -1
//递归遍历:8 4 9 2 10 5 1 6 3 7
//非递归遍历:8 4 9 2 10 5 1 6 3 7
注意(中序与先序的代码区别)
- 在递归算法实现上:中序遍历只需要将访问根结点的输出语句放在访问左子树的代码下面,即改变先序遍历的顺序就好。
- 在非递归算法实现上:中序遍历只需将访问当前结点的输出语句放在出栈的代码下面,而不是入栈时先访问(输出)。即访问当前结点时,不输出而直接将其入栈,继续先访问其左子树,待左子树访问完后(即当前结点为空),将栈中元素出栈,然后访问(输出)出栈的元素,再继续访问其右子树。