二叉树是一种非常重要的数据结构,其中遍历二叉树是二叉树最基本的操作,也是二叉树其他各种操作的基础。根据节点访问顺序的不同,二叉树的常见遍历方式有4种常见的遍历方式(Preorder Traversal):
- 前序遍历
- 中序遍历
- 后序遍历
- 层序遍历
首先给出二叉树的结构
typedef struct BiNode {
char data;
struct BiNode* Lchild, * Rchild;
}BiNode, * BiTree;
以下图所示的二叉树为例,用#代表空结点
以前序遍历的结果输入:ABD##E##CF###
前序遍历
前序遍历就是先访问根结点,然后再依次访问左右节点
1、以递归方式
void PreOrderTraverse(BiTree T){
if(T){ //结点不为空
cout << T->data; //输出当前结点
PreOrderTraverse(T->Lchild); //遍历左节点
PreOrderTraverse(T->Rchild); //遍历右节点
}
}
2、非递归方式
非递归的遍历方式需要使用栈,在这里借助C++中的栈来实现遍历
void PreOrderTraverse(BiTree T){
stack<BiTree>stk;
BiTree p = T;
stk.push(T); //将根结点入栈
while(!stk.empty()){
p = stk.top(); //获取栈顶元素
stk.pop();
cout << p->data;
if(p->Rchild != NULL){
stk.push(p->Rchild);
}
if(p->Lchild != NULL){
stk.push(p->Lchild);
}
}
}
中续遍历
中序遍历先访问左节点,然后访问根结点和右节点
1、递归方式
void InOrderTraverse(BiTree T){
if (T) {
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
2、非递归方式
void InOrderTraverse(BiTree T){
BiTree p = T;
BiNode *tem;
stack<BiTree>stk;
while(p || !sta.empty()){
if(p){
stk.push(p); //将当前节点入栈
p = p->Lchild; //指向左节点
}
else{
tem = stk.top();
cout << tem->data;
stk.pop();
p = tem->Rchild;
}
}
}
后续遍历
后序遍历先访问左节点,再访问右节点,最后访问根结点
void PostOrderTraverse(BiTree T){
if(T){
PostOrderTraverse(T->Lchild);
PostOrderTraverse(T->Rchild);
cout << T->data;
}
}
层序遍历
层序遍历访问顺序是从上到下、从左到右依次访问每一个节点
层序遍历需要依靠队列来实现
void LevelOrder(BiTree T){
BiNode* p;
queue<BiTree>q;
q.push(T);
while(!q.empty()){
p = q.front(); //获得队头元素
q.pop();
cout << p->data;
if (p->lchild != NULL) { //左节点入队
q.push(p->lchild);
}
if (p->rchild != NULL) { //右节点入队
q.push(p->rchild);
}
}
}
最终的运行结果为