#include<iostream>
#include<stack>
#include<queue>
using namespace std;
typedef char ElementTYPE;
//结构体定义
typedef struct Node{
ElementTYPE data;
struct Node *lchild;
struct Node *rchild;
}BinaryTree,*BiTree;
class initTree{
public:
//先序建立
int k=0;
BinaryTree* createBinaryTree(BinaryTree* &T,char ch[],int l){ //需要注意的地方,&T使用二重指针,而单链表使用的是一重指针
ElementTYPE data = ch[k];
T = new BinaryTree();
if(data=='#'){
T = NULL;
}
else{
T->data = data;
createBinaryTree(T->lchild,ch,k++);
createBinaryTree(T->rchild,ch,k++);
}
return T;
}
}init;
//二叉树递归遍历三种方法
class recursion{
public:
void visit(BinaryTree* T){
cout<<T->data<<" ";
}
//先序遍历
void preOrder(BinaryTree* T){
if(T!=NULL)
{
visit(T);
preOrder(T->lchild);
preOrder(T->rchild);
}
}
//中序遍历
void inOrder(BinaryTree* T){
if(T!=NULL)
{
inOrder(T->lchild);
visit(T);
inOrder(T->rchild);
}
}
//后序遍历
void postOrder(BinaryTree* T){
if(T!=NULL)
{
postOrder(T->lchild);
postOrder(T->rchild);
visit(T);
}
}
}recur;
//二叉树非递归遍历四种方法
class non_recursion{
public:
void visit(ElementTYPE data){
cout<<data<<" ";
}
//先序遍历
/* 思路:将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。*/
void preOrder(BinaryTree* T){
BinaryTree* p = T;
stack<BinaryTree*> stack;
while(p || !stack.empty())
if(p){
stack.push(p);//给的是树的地址,而不是值
visit(p->data);
p = p->lchild;
}else{
p = stack.top();//p返回到当前树的父节点地址
stack.pop();//删除节点
p = p->rchild;//访问右子树
}
}
//中序遍历 指针p从根节点开始,首先沿着左子树向下移动,同时入栈保存,当到达空子树后需要退栈访问,然后移动到右子树上去
void inOrder(BinaryTree* T){
BinaryTree* p = T;
stack<BinaryTree*> stack;
while(p || !stack.empty())
if(p){
stack.push(p);
p = p->lchild;
}else{
p = stack.top();//退栈
stack.pop();
visit(p->data);//退栈时输出节点
p = p->rchild;
}
}
//非递归后序遍历 后序遍历时,分别从左子树和右子树共两次返回根节点,只有从右子树返是才访问根节点,所以增加一个栈标记到达节点的次序
typedef struct BiTNodePost{
BiTree biTree;
char tag;
}BiTNodePost, *BiTreePost;
void postOrder(BiTree T)
{
stack<BiTreePost> stack;
//p是遍历指针
BiTree p = T;
BiTreePost BT;
//栈不空或者p不空时循环
while (p != NULL || !stack.empty())
{
//遍历左子树
while (p != NULL)
{
BT = new BiTNodePost;
BT->biTree = p;
//访问过左子树
BT->tag = 'L';
stack.push(BT);
p = p->lchild;
}
//左右子树访问完毕访问根节点
while (!stack.empty() && (stack.top())->tag == 'R')
{
BT = stack.top();
//退栈
stack.pop();
cout<<BT->biTree->data<<" ";
}
//遍历右子树
if (!stack.empty())
{
BT = stack.top();
//访问过右子树
BT->tag = 'R';
p = BT->biTree;
p = p->rchild;
}
}
}
//层次遍历
void LevelOrder(BiTree T)
{
BiTree p = T;
queue<BiTree> queue;
//根节点入队
queue.push(p);
//队列不空循环
while (!queue.empty())
{
//对头元素出队
p = queue.front();
//访问p指向的结点
visit(p->data);
//退出队列
queue.pop();
//左孩子不为空,将左孩子入队
if (p->lchild != NULL)
{
queue.push(p->lchild);
}
//右孩子不空,将右孩子入队
if (p->rchild != NULL)
{
queue.push(p->rchild);
}
}
}
}non_recur;
// int main(){
// char ch[] = {'1','2','4','8','#','#','9','#','#','5','#','#','3','6','#','#','7','#','#'};
// int len = sizeof(ch)/sizeof(ch[0]);
// BinaryTree* T;
// T = init.createBinaryTree(T,ch,0);
// //递归:
// cout<<"递归先序:"; recur.preOrder(T);
// cout<<"\n递归中序:"; recur.inOrder(T);
// cout<<"\n递归后序:"; recur.postOrder(T);
// //非递归:
// cout<<"\n非递归先序:"; non_recur.preOrder(T);
// cout<<"\n非递归中序:"; non_recur.inOrder(T);
// cout<<"\n非递归后序:"; non_recur.postOrder(T);
// cout<<"\n层次遍历:"; non_recur.LevelOrder(T);
// }