/*************************************************************/
/* 三、二叉树的遍历
/* 1.输入一个完全二叉树的层次遍历字符串,创建这个二叉树,
/* 输出这个二叉树的前序遍历字符串、中序遍历字符串、
/* 后序遍历字符串、结点数目、二叉树高度。
/* 2.输入二叉树前序序列和中序序列(各元素各不相同),
/* 创建这个二叉树,输出该二叉树的后序序列。
/*************************************************************/
//链表描述二叉树的创建与遍历
#include <iostream>
#include <string>
#include <queue>
#include <stack>
using namespace std;
using std::queue;
using std::stack;
#define MAX 100 //前中序输入的最大数目
static string outputString="";
/**********************************/
/*以下内容是一个二叉树数据结构定义*/
/**********************************/
template<class T>
class BinaryTreeNode
{
public:
BinaryTreeNode(){LeftChild=RightChild=0;}
BinaryTreeNode(const T&e){data=e;LeftChild=RightChild=0;}
BinaryTreeNode(const T&e,BinaryTreeNode *l,BinaryTreeNode *r){data=e;LeftChild=l;RightChild=r;}
T data;
BinaryTreeNode<T>*LeftChild; //左子树
BinaryTreeNode<T>*RightChild; //右子树
};
/**********************************/
/*以下内容是一个二叉树临时元素定义*/
/**********************************/
#ifndef STACKELEMENT_H
#define STACKELEMENT_H
//StackElement结构的定义是为了解决非递归后序遍历问题
enum Tags{Left,Right};
template<class T>
struct StackElement{
BinaryTreeNode<T>* pointer;
Tags tag;
};
#endif
template<class T>
class BinaryTree
{
public:
BinaryTree(){root=0;}
~BinaryTree(){};
bool IsEmpty()const{return ((root)?false:true)}; //如果root存在则为false,也就是不为空。
bool Root(T&x)const;
void MakeTree(const T&element,BinaryTree<T>&left,BinaryTree<T>&right);
void MakeTree(BinaryTreeNode<T>*r){root=r;}
void BreakTree(T&element,BinaryTree<T>&left,BinaryTree<T>&right);
void PreOrder(void(*Visit)(BinaryTreeNode<T>*u)){PreOrder(Visit,root);}
void InOrder(void(*Visit)(BinaryTreeNode<T>*u)){InOrder(Visit,root);}
void PostOrder(void(*Visit)(BinaryTreeNode<T>*u)){PostOrder(Visit,root);}
void LevelOrder(void(*Visit)(BinaryTreeNode<T>*u)){LevelOrder(Visit,root);};
//二叉树类的扩充
void PreOutput();
void InOutput();
void PostOutput();
void LevelOutput();
void Delete(); //删除二叉树并释放其节点
void AddNode(const T&u); //删除二叉树并释放其节点
int Height(BinaryTreeNode<T>*t)const; //返回树的高度
int Size(); //返回树中的节点数
BinaryTreeNode<T>*root;
void PreOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t);
void InOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t);
void PostOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t);
void LevelOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t);
};
//取根节点的data域
//如果没有根节点则返回false
template<class T>
bool BinaryTree<T>::Root(T&x)const
{
if(root)
{
x=root->data;
return true;
}
else
{
return false;
}
}
//将left,right,element合并成一颗新树
//left、right和this必须是不同的树
template<class T>
void BinaryTree<T>::MakeTree(const T&element,BinaryTree<T>&left,BinaryTree<T>&right)
{
root = new BinaryTreeNode<T>(element,left.root,right.root);
left.root=right.root=0; //禁止通过其他途径访问left和right
}
void BadInput(){
cout<<"Bad Input!"<<endl;
}
//将this拆分成left、right和element
//left、right和this必须是不同的树
template<class T>
void BinaryTree<T>::BreakTree(T&element,BinaryTree<T>&left,BinaryTree<T>&right)
{
if(root)
throw BadInput();//空树
//分解树
element=root->data;
left.root=root->LeftChild;
right.root=root->RightChild;
delete root;
root = 0;
}
//静态成员函数Output输出树
template<class T>
static void Output(BinaryTreeNode<T>*t)
{
outputString+=t->data;
outputString+=",";
}
template<class T>
void BinaryTree<T>::PreOutput()
{
outputString="";
PreOrder(Output,root);
outputString.erase(outputString.end()-1);
cout<<outputString<<endl;
}
template<class T>
void BinaryTree<T>::InOutput()
{
outputString="";
InOrder(Output,root);
outputString.erase(outputString.end()-1);
cout<<outputString<<endl;
}
template<class T>
void BinaryTree<T>::PostOutput()
{
outputString="";
PostOrder(Output,root);
outputString.erase(outputString.end()-1);
cout<<outputString<<endl;
}
template<class T>
void BinaryTree<T>::LevelOutput()
{
outputString="";
LevelOrder(Output,root);
outputString.erase(outputString.end()-1);
cout<<outputString<<endl;
}
template<class T>
void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t)
{
/*************使用递归实现的遍历***************
if(t)
{
Visit(t);
PreOrder(Visit,t->LeftChild);
PreOrder(Visit,t->RightChild);
}
/**********************************************/
/************使用非递归实现的遍历**************/
stack<BinaryTreeNode<T>*>myStack;
BinaryTreeNode<T>*pointer = root;
while(!myStack.empty()||pointer)//栈不空或者pointer不空
{
if(pointer)
{
Visit(pointer); //访问当前节点
myStack.push(pointer); //当前节点地址入栈
pointer=pointer->LeftChild; //访问左边分支
}
else //左子树访问完毕
{
pointer=myStack.top();
myStack.pop();
pointer=pointer->RightChild;
}
}
}
template<class T>
void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t)
{
/*************使用递归实现的遍历***************
if(t)
{
InOrder(Visit,t->LeftChild);
Visit(t);
InOrder(Visit,t->RightChild);
}
/**********************************************/
/************使用非递归实现的遍历**************/
stack<BinaryTreeNode<T>*>myStack;
BinaryTreeNode<T>*pointer = root;
while(!myStack.empty()||pointer)//栈不空或者pointer不空
{
if(pointer)
{
myStack.push(pointer); //当前节点地址入栈
pointer=pointer->LeftChild; //访问左边分支
}
else //左子树访问完毕
{
pointer=myStack.top();
Visit(pointer); //访问当前节点
myStack.pop();
pointer=pointer->RightChild;
}
}
}
template<class T>
void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t)
{
/*************使用递归实现的遍历***************/
if(t)
{
PostOrder(Visit,t->LeftChild);
PostOrder(Visit,t->RightChild);
Visit(t);
}
/**********************************************/
/************使用非递归实现的遍历**************
StackElement<T>element;
stack<StackElement<T>>myStack;
BinaryTreeNode<T>*pointer;
if(root==NULL)
return;
pointer=root;
while(true)
{
while(pointer!=NULL)
{
element.pointer = pointer;
element.tag=Left;
myStack.push(element);
pointer=pointer->LeftChild;
}
element=myStack.top();
myStack.pop();
pointer=element.pointer;
//从右子树回来
while(element.tag==Right)
{
Visit(pointer->data);
if (myStack.empty())
{
return
}
else
{
element=myStack.top();
myStack.pop();
pointer=element.pointer;
}
//从左子树回来
element.tag = Right;
myStack.push(element);
//转向访问右子树
pointer=pointer->RightChild;
}
}
/**********************************************/
}
template<class T>
void BinaryTree<T>::LevelOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t)
{
queue<BinaryTreeNode<T>*>myQueue;
while(t)
{
Visit(t);
if(t->LeftChild)
myQueue.push(t->LeftChild);
if(t->RightChild)
myQueue.push(t->RightChild);
if(!myQueue.empty())
{
t=myQueue.front();
myQueue.pop();
}else{
break;
}
}
}
template<class T>
void BinaryTree<T>::AddNode(const T&u){
if(!root)
{
root = new BinaryTreeNode<T>;
root->data = u;
root->LeftChild=0;
root->RightChild=0;
return ;
}
BinaryTreeNode<T> *newNode = new BinaryTreeNode<T>;
newNode->data = u;
queue<BinaryTreeNode<T>*>myQueue;
BinaryTreeNode<T>*t;
t=root;
while(t)
{
if(t->LeftChild){
myQueue.push(t->LeftChild);
}
if(t->RightChild){
myQueue.push(t->RightChild);
}
if(!t->LeftChild)
{
t->LeftChild=newNode;
return;
}else{
}
if(!t->RightChild)
{
t->RightChild=newNode;
return;
}else{
}
if(!myQueue.empty())
{
t=myQueue.front();
myQueue.pop(); //队列中删除一个节点并且将其赋值给t
}
}
}
template<class T>
static void Free(BinaryTreeNode<T>*t)
{
delete t;
}
template<class T>
void BinaryTree<T>::Delete()
{
PostOrder(Free,root);
root = 0;
}
template<class T>
int BinaryTree<T>::Height(BinaryTreeNode<T>*t)const
{
if(!t)
return 0;
int hl = Height(t->LeftChild);
int hr = Height(t->RightChild);
return hl>hr?++hl:++hr;
}
template<class T>
int BinaryTree<T>::Size()
{
count = 0 ;
PreOrder(countTree,root);
return count;
}
int count = 0;
BinaryTree<char> a,x,y,z;
template<class T>
void countTree(BinaryTreeNode<T>*t)
{
count++;
}
BinaryTreeNode<char>* creat(char *pre,char *in,int len)
{
int k;
if(len<=0)
return NULL;
BinaryTreeNode<char> *head=new BinaryTreeNode<char>;
head->data=*pre;
char *p;
for(p=in;*p!=NULL;p++) //应该是*p!= NULL, 而不是p!=NULL
if(*p==*pre)
break;
//判断失败
if (*p == NULL)
{
printf("NO ANSWER.\n");
return NULL;
}
k=p-in;
head->LeftChild=creat(pre+1,in,k);
head->RightChild=creat(pre+k+1,p+1,len-k-1);
return head;
}
void main()
{
cout<<"Input1"<<endl;
string myInput=" ";
cin>>myInput;
int which = 0;
while(myInput[which])
{
char temp = myInput[which];
y.AddNode(temp);
which++;
}
cout<<"Output1"<<endl;
y.PreOutput();
y.InOutput();
y.PostOutput();
cout<<"Input2"<<endl;
string input1;
cin>>input1;
string input2;
cin>>input2;
char*preOrder=(char*)input1.c_str();
char*inOrder=(char*)input2.c_str();
BinaryTreeNode<char>*myRoot = creat(preOrder,inOrder,input2.length());
BinaryTree<char>newTree;
newTree.MakeTree(myRoot);
cout<<"Output2"<<endl;
newTree.PostOutput();
newTree.LevelOutput();
cout<<"End"<<endl;
}
[C++]数据结构实验05:二叉树的遍历
最新推荐文章于 2024-04-29 19:59:18 发布
这篇博客详细介绍了如何用C++实现二叉树的遍历,包括前序遍历、中序遍历、后序遍历以及层次遍历。同时,还涵盖了如何根据前序和中序序列构建二叉树,并输出相应的后序序列。博客内容包括了二叉树节点的定义、链表描述二叉树的创建与遍历、以及相关的遍历算法实现,如递归和非递归方法。
摘要由CSDN通过智能技术生成