基本概念
二叉树的遍历
:指按某条搜索路径访问树中每个结点,使得每个结点均被访问一次, 而且仅被访问一次。
先序遍历:按照
根-左-右 的次序遍历。
图例
先序遍历序列为:1 2 4 8 9 5 10 3 6 7
代码
二叉树结构体
typedef struct BiTNode{
int val;//根结点的值
struct BiTNode *lchild,*rchild;//左孩子指针 右孩子指针
}BiTNode,*BiTree;
构建二叉树
//二叉树构造函数
BiTree createTree(){
int val;
cin>>val;
if(val==-1) return NULL;
BiTNode *T=(BiTNode *)malloc(sizeof(BiTNode));
T->val =val;
T->lchild =createTree();
T->rchild =createTree();
}
递归法遍历
//递归法遍历
void preorder(BiTree T){
if(T){//这里不加非空判断,不然遇到叶子结点后就不能递归下去了
cout<<T->val<<" ";//遍历根结点
preorder(T->lchild);//遍历左子树
preorder(T->rchild);//遍历右子树
}
}
非递归法遍历
//非递归法遍历
void preorder1(BiTree T){
if(!T) return;
stack<BiTNode *> st;//初始化栈
BiTNode *p=T;//用一个p指针来遍历
while(p||!st.empty()){//循环条件:当前结点不为空或者栈不为空(重要!!!)
if(p){//若当前结点不为空
cout<<p->val <<" ";//遍历当前结点
st.push(p);//遍历过的结点进栈
p=p->lchild ;//访问左子树结点
}
else{//当前结点为空
p=st.top();//取出栈顶元素
st.pop();//弹出栈顶元素
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;
BiTNode *T=(BiTNode *)malloc(sizeof(BiTNode));
T->val =val;
T->lchild =createTree();
T->rchild =createTree();
}
//递归法遍历
void preorder(BiTree T){
if(T){//这里不加非空判断,不然遇到叶子结点后就不能递归下去了
cout<<T->val<<" ";//遍历根结点
preorder(T->lchild);//遍历左子树
preorder(T->rchild);//遍历右子树
}
}
//非递归法遍历
void preorder1(BiTree T){
if(!T) return;
stack<BiTNode *> st;//初始化栈
BiTNode *p=T;//用一个p指针来遍历
while(p||!st.empty()){//循环条件:当前结点不为空或者栈不为空(重要!!!)
if(p){//若当前结点不为空
cout<<p->val <<" ";//遍历当前结点
st.push(p);//遍历过的结点进栈
p=p->lchild ;//访问左子树结点
}
else{//当前结点为空
p=st.top();//取出栈顶元素
st.pop();//弹出栈顶元素
p=p->rchild ;//访问右子树节点
}
}
}
int main(){
BiTree T=createTree();
cout<<"递归遍历结果:"<<endl;
preorder(T);
cout<<endl;
cout<<"非递归遍历结果:"<<endl;
preorder1(T);
return 0;
}
//二叉树先序序列:1 2 4 8 -1 -1 9 -1 -1 5 10 -1 -1 -1 3 6 -1 -1 7 -1 -1
//递归遍历:1 2 4 8 9 5 10 3 6 7
//非递归遍历:1 2 4 8 9 5 10 3 6 7
注意
- 这里采用先序+为叶子结点添加‘-1’作为孩子节点来唯一确定一棵二叉树。
- 非递归代码中,注意遍历过的结点加入栈中,这样当遍历完左子树的时候可以从栈中取出他的根结点,从而遍历右子树。