#include "stdafx.h"
#include <vector>
#include<iostream>
using namespace std;
typedef struct BiTNode{
char data;
BiTNode *lchild,*rchild; //左右孩子的指针
}*BiTree;
//先序创建一个二叉树
int CreateBiTree(BiTree &T,string &str,int *index)
{
//index为字符串的序数的指针
//#代表结束
//string str="AB#D##C##"; //测试树
if ((*index)<str.size())
{
char t_nodeData=str[(*index)++];
if(t_nodeData=='#') T=NULL;
else
{
if(!(T=new (BiTNode))) throw runtime_error("OVERFLOW");
T->data = t_nodeData; // 生成根节点
CreateBiTree(T->lchild,str,index); // 创建左子树
CreateBiTree(T->rchild,str,index); // 创建右子树
}
}
return 0;
}
//递归先序遍历二叉树,输出节点的值
void PreOrderTraverse1(BiTree T)
{
if (!T) return;
cout<<T->data<<endl;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
//栈的方式先序遍历二叉树
void PreOrderTraverse2(BiTree T)
{
vector<BiTree> t_vTree;
BiTree p=T;
while (p || !t_vTree.empty())
{
if (p){
cout<<p->data<<" "; //访问每个节点的数据,输出结果
t_vTree.push_back(p);
p = p->lchild;
}
else{ //此节点结束,开始访问右子树
p = t_vTree.back()->rchild;
t_vTree.pop_back();
}
} //while
cout<<endl;
}
//中序遍历二叉树,栈的方式1,两个while循环
void InOrderTraverse1(const BiTree T){
//采用二叉链表存储结构,中序非递归算法一
vector<BiTNode*> t_vTree;
BiTree p;
t_vTree.push_back(T);
while (!t_vTree.empty())
{
p = t_vTree.back();
while(p)
{
t_vTree.push_back(p->lchild); //向左走到尽头
p = p->lchild;
}
t_vTree.pop_back(); //最后一个压栈的是个空指针
if(!t_vTree.empty())
{
cout<<t_vTree.back()->data<<' ';
BiTree t_pReserve= t_vTree.back()->rchild; //保留当前指针的右子树指针
t_vTree.pop_back();
t_vTree.push_back(t_pReserve); //开始压栈右子树
}
}
}
//中序遍历二叉树,栈的方式2,1个while循环
void InOrderTraverse2(const BiTree T){
vector<BiTree> t_vTree;
BiTree p=T;
while (p || !t_vTree.empty())
{
if (p){
t_vTree.push_back(p);
p = p->lchild;
}
else{ //此节点结束,开始访问右子树
cout<<t_vTree.back()->data<<endl; //访问每个节点的数据,输出结果
p = t_vTree.back()->rchild;
t_vTree.pop_back();
}
} //while
}
//后序非递归遍历
void PostOrderTraverse(const BiTree T){
vector<BiTree> t_vTree;
BiTree p=T;
BiTree have_visited=NULL; //指示节点是否被访问
while (p || !t_vTree.empty())
{
if (p){
t_vTree.push_back(p);
p = p->lchild;
}
else{
p = t_vTree.back(); //此时P为空指针,将栈顶的节点弹出
if (p->rchild==NULL ||p->rchild==have_visited)
{
cout<<p->data<<endl; //访问每个节点的数据,输出结果
have_visited=p; //标记为已访问
t_vTree.pop_back();
p = NULL;
}
else p=p->rchild;
}
} //while
}
int main()
{
string str="AB#D##C##"; //测试树
int index=0;
BiTNode *T;
CreateBiTree(T,str,&index);
PreOrderTraverse2(T);
//PostOrderTraverse(T);
return 0;
}
二叉树的基本操作,前序遍历,后续遍历,中序遍历
最新推荐文章于 2020-09-07 15:35:48 发布