二叉树的遍历
所谓二叉树的遍历是指按某条搜索路径访问树中的每个结点,使得每个结点均被访问一次。
先序遍历
1.访问根节点
2.先序遍历左子树
3.先序遍历右子树
void preOrder(BiTree T)
{
if(T != nullptr){
visit(T);
preOrder(T->left);
preOrder(T->right);
}
}
中序遍历
1.中序遍历左子树
2.访问根结点
3.中序遍历右子树
void inOrder(BiTree T)
{
if(T!=nullptr){
inOrder(T->left);
visit(T);
inOrder(T->right);
}
}
后序遍历
1.后序遍历左子树
2.后序遍历右子树
3.访问根结点
void postOrder(BiTree T)
{
if(T != nullptr){
postOrder(T->left);
postOrder(T->right);
visit(T);
}
}
以上是递归版本,我们其实可以根据上述过程利用栈来将递归改为非递归,后序遍历的非递归稍微有点绕,主要是分清楚返回根结点时,是从左子树返回的还是右子树返回的,所以需要用一个标记来表示是否已经被访问过,程序中标记为1的表示被访问过一次。三种非递归的完整算法以及测试样例如下:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <malloc.h>
#include <stack>
#include <queue>
#include <bits/stdc++.h>
using namespace std;
char str[100];
typedef struct BiTNode{
char data;
struct BiTNode *left,*right;
}BiTNode,*BiTree;
BiTree build()
{
char c;
BiTree st = NULL;
c=getchar();
if(c!='#')
{
st = new BiTNode();
st ->data = c;//已知为先序遍历,先填充根节点
st ->left = build();//递归形式填充左分支
st ->right = build();//递归形式填充左分支
}
return st;
}
void visit(BiTNode *x)
{
cout<<x->data<<' ';
}
void preOrder(BiTree T)
{
if(T != nullptr){
visit(T);
preOrder(T->left);
preOrder(T->right);
}
}
void inOrder(BiTree T)
{
if(T != nullptr){
inOrder(T->left);
visit(T);
inOrder(T->right);
}
}
void postOrder(BiTree T)
{
if(T != nullptr){
postOrder(T->left);
postOrder(T->right);
visit(T);
}
}
//先序非递归
void preVisitStack(BiTree root)
{
stack<BiTNode*> st;
BiTNode *p = root;
while (p || !st.empty()) {
if (p) {
visit(p);
st.push(p);
p = p->left;
} else {
p = st.top();
st.pop();
p = p->right;
}
}
}
//中序非递归
void midVisitStack(BiTree root)
{
stack<BiTNode*> st;
BiTNode *p = root;
while (p || !st.empty()) {
if (p) {
st.push(p);
p = p->left;
} else {
p = st.top();
visit(p);
st.pop();
p = p->right;
}
}
cout << endl;
}
//后序非递归
void backVisitStack(BiTree root)
{
stack<pair<BiTNode*, int> > st;
BiTNode *p = root;
while (p || !st.empty()) {
if (p) {
st.push(make_pair(p, 1));
p = p->left;
} else {
pair<BiTNode*, int> now = st.top();
st.pop();
if (now.second == 1) {
st.push(make_pair(now.first, 2));
p = now.first->right;
} else
visit(now.first);
}
}
cout << endl;
}
/* 树的结构
A
/ \
B C
/ \ /
D E F
/ \
G H
*/
//先序序列 ABDG###E#H##CF###
// 根据先序 建树
int main()
{
BiTree bt;
bt = build();
// preOrder(bt);
cout<<"先序序列"<<endl;
preVisitStack(bt);
cout<<"\n中序序列"<<endl;
midVisitStack(bt);
//inOrder(bt);
cout<<"后序序列"<<endl;
backVisitStack(bt);
return 0;
}