题目:
1. 定义二叉树类,封装构造二叉树基本操作,广度优先遍历,深度优先遍历(递归和非递归算法)等。
2. 实现由先序、中序序列构造二叉树的算法。
3. 实现由后序、中序序列构造二叉树的算法。
//
// main.cpp
// BinaryTree
//
// Created by Cyril on 2016/11/8.
// Copyright © 2016年 Cyril. All rights reserved.
//
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
//二叉树结点的定义
template <class T>
class BT;
template <class T>
class BTNode
{
friend class BT<T>;
private:
T data;
BTNode *lChild;
BTNode *rChild;
public:
BTNode();
BTNode(T& d);//给定数据域的值得构造函数
BTNode(T& d, BTNode *l, BTNode *r);//给定数据域以及左右孩子的构造函数
BTNode<T> *GetLChild();//返回左孩子结点的指针
BTNode<T> *GetRChild();//返回右孩子结点的指针
void SetLChild(BTNode<T> *l);//设置左孩子结点
void SetRChild(BTNode<T> *r);//设置右孩子结点
~BTNode(){}
T GetValue();//返回该节点数据值
bool SetValue(T& val);//设置该点数据值
bool IsLeaf();//判断是否为叶子结点
void DisplayNode();//输出结点
};
template <class T>
BTNode<T>::BTNode()
{
lChild=rChild=NULL;
}
template <class T>
BTNode<T>::BTNode(T& d)//给定数据域的值得构造函数
{
lChild=rChild=NULL;
data=d;
}
template <class T>
BTNode<T>::BTNode(T& d, BTNode *l, BTNode *r)//给定数据域以及左右孩子的构造函数
{
lChild=l;
rChild=r;
data=d;
}
template <class T>
BTNode<T>* BTNode<T>:: GetLChild()//返回左孩子结点的指针
{
return lChild;
}
template <class T>
BTNode<T>* BTNode<T>:: GetRChild()//返回右孩子结点的指针
{
return rChild;
}
template <class T>
void BTNode<T>:: SetLChild(BTNode<T> *l)//设置左孩子结点
{
lChild=l;
}
template <class T>
void BTNode<T>:: SetRChild(BTNode<T> *r)//设置右孩子结点
{
rChild=r;
}
template <class T>
T BTNode<T>:: GetValue()//返回该节点数据值
{
return data;
}
template <class T>
bool BTNode<T>:: SetValue(T& val)//设置该点数据值
{
this->data=val;
return true;
}
template <class T>
bool BTNode<T>:: IsLeaf()//判断是否为叶子结点
{
if(lChild==NULL&&rChild==NULL)
return true;
else
return false;
}
template <class T>
void BTNode<T>:: DisplayNode()//输出结点
{
cout<<"该结点的数据为: "<<data<<endl;
}
//二叉树类的定义
template <class T>
class BT
{
private:
BTNode<T> *root;//二叉树的根节点
public:
BT(){root=NULL;}
~BT(){}
void NewTree();//创建新树
BTNode<T>* SetSubTree();//创建子树并返回子树的根结点地址
bool IsEmpty();//判断是否为空树
BTNode<T>* GetRoot();//返回根节点
bool GetParent(BTNode<T> *cur);//返回当前结点的父节点.(未实现)
bool GetLSibling(BTNode<T> *cur);//返回当前结点的左兄弟.(未实现)
bool GetRSibling(BTNode<T> *cur);//返回当前结点的右兄弟.(未实现)
bool LevelOrder(BTNode<T> *r);//广度优先遍历(非递归)
bool PreOrder(BTNode<T> *r);//前序遍历(递归)
bool PreOrderWithoutRecusion(BTNode<T> *r);//前序遍历(非递归)
bool InOrder(BTNode<T> *r);//中序遍历(递归)
bool InOrderWithoutRecusion(BTNode<T> *r);//中序遍历(非递归)
bool PostOrder(BTNode<T> *r);//后序遍历(递归)
bool PostOrderWithoutRecusion(BTNode<T> *r);//后序遍历(非递归)
bool DeleteNode(BTNode<T> *r);//删除以r为根结点的子树.(未实现)
void Display();//输出树
void RecDisplay(BTNode<T> *t);//用于输出树时的循环迭代
void PreInCreateTree(string &pre, string &in);//前序中序构造二叉树
BTNode<T>* PreInCreate(string &pre, string &in);//用于前序、中序构造二叉树
void PostInCreateTree(string &post, string &in);//后序中序构造二叉树
BTNode<T>* PostInCreate(string &post, string &in);//用于后序、中序构造二叉树
};
template <class T>
void BT<T>::NewTree()//创建新树
{
cout<<"请输入根结点的数据:"<<endl;
root=SetSubTree();
}
template <class T>
BTNode<T>* BT<T>::GetRoot()//返回根节点
{
return root;
}
template <class T>
BTNode<T>* BT<T>:: SetSubTree()//创建子树并返回子树的根结点地址
{
T t;
cin>>t;
BTNode<T> *p;
if(t=='#')
return NULL;//返回空指针
else
{
p=new BTNode<T>;
p->SetValue(t);
//cout<<"成功读入"<<t<<endl;
cout<<"请输入左孩子结点的数据:(输入‘#’则表示不存在左孩子结点)"<<endl;
p->SetLChild(SetSubTree());
cout<<"请输入右孩子结点的数据:(输入‘#’则表示不存在左孩子结点)"<<endl;
p->SetRChild(SetSubTree());
return p;
}
}
template <class T>
bool BT<T>:: IsEmpty()//判断是否为空树
{
return !root;
}
template <class T>
BTNode<T>* BT<T>:: PreInCreate(string &pre, string &in)//用于前序、中序构造二叉树
{
if(pre.length()!=in.length())
return NULL;//长度不一样则返回错
char ele;//临时存储字符
BTNode<T> *p;
ele=pre[0];
if(!ele)
return NULL;
else
{
p=new BTNode<T>;
p->SetValue(ele);
int index=(int)in.find(ele);
string PreLeft=pre.substr(1,index);
string InLeft=in.substr(0,index);
string PreRight=pre.substr(index+1);
string InRight=in.substr(index+1);
p->SetLChild(PreInCreate(PreLeft,InLeft));
p->SetRChild(PreInCreate(PreRight,InRight));
return p;
}
}
template <class T>
void BT<T>:: PreInCreateTree(string &pre, string &in)//前序中序构造二叉树
{
root=PreInCreate(pre,in);
}
//
template <class T>
BTNode<T>* BT<T>:: PostInCreate(string &post, string &in)//用于后序、中序构造二叉树
{
if(post.length()!=in.length())
return NULL;//长度不一样则返回错
char ele;//临时存储字符
BTNode<T> *q;
if(!post[0])
return NULL;
else
{
ele=post[post.length()-1];
q=new BTNode<T>;
q->SetValue(ele);
int index=(int)in.find(ele);
string PostLeft=post.substr(0,index);
string InLeft=in.substr(0,index);
string PostRight=post.substr(index,in.length()-(index+1));
string InRight=in.substr(index+1);
q->SetLChild(PostInCreate(PostLeft,InLeft));
q->SetRChild(PostInCreate(PostRight,InRight));
return q;
}
}
template <class T>
void BT<T>:: PostInCreateTree(string &post, string &in)//后序中序构造二叉树
{
root=PostInCreate(post,in);
}
template <class T>
bool BT<T>:: LevelOrder(BTNode<T> *r)//广度优先遍历(非递归)
{
queue<BTNode<T>*> NodeQueue;
BTNode<T> *p=root;
if(p)
NodeQueue.push(p);
while (!NodeQueue.empty())
{
p=NodeQueue.front();
//...访问p指针指向的结点
//样例操作:广度优先输出树
cout<<p->data<<' ';
NodeQueue.pop();
if(p->lChild)
NodeQueue.push(p->lChild);
if(p->rChild)
NodeQueue.push(p->rChild);
}
return true;
}
template <class T>
bool BT<T>:: PreOrder(BTNode<T> *r)//前序遍历(递归)
{
if(r)
{
//...访问r指针指向的结点
//样例操作:深度优先输出树
cout<<r->data<<' ';
PreOrder(r->lChild);
PreOrder(r->rChild);
}
return true;
}
template <class T>
bool BT<T>:: InOrder(BTNode<T> *r)//中序遍历(递归)
{
if(r)
{
InOrder(r->lChild);
//...访问r指针指向的结点
//样例操作:深度优先输出树
cout<<r->data<<' ';
InOrder(r->rChild);
}
return true;
}
template <class T>
bool BT<T>:: PostOrder(BTNode<T> *r)//后序遍历(递归)
{
if(r)
{
PostOrder(r->lChild);
PostOrder(r->rChild);
//...访问r指针指向的结点
//样例操作:深度优先输出树
cout<<r->data<<' ';
}
return true;
}
template <class T>
bool BT<T>:: PreOrderWithoutRecusion(BTNode<T> *r)//前序遍历(非递归)
{
BTNode<T> *p;
p=r;
stack<BTNode<T>*> NodeStack;
while (!NodeStack.empty()||p)//栈为空或还有结点
{
if(p)
{
//...访问p指针指向的结点
//深度优先输出树
cout<<p->data<<' ';
if(p->rChild)
{
NodeStack.push(p->rChild);
}
p=p->lChild;
}
else
{
p=NodeStack.top();
NodeStack.pop();
}
}
return true;
}
template <class T>
bool BT<T>:: InOrderWithoutRecusion(BTNode<T> *r)//中序遍历(非递归)
{
BTNode<T> *p;
p=r;
stack<BTNode<T>*> NodeStack;
while (!NodeStack.empty()||p)//栈为空或还有结点
{
if(p)
{
NodeStack.push(p);
p=p->lChild;
}
else
{
p=NodeStack.top();
NodeStack.pop();
//...访问p指针指向的结点
//深度优先输出树
cout<<p->data<<' ';
p=p->rChild;
}
}
return true;
}
template <class T>
bool BT<T>:: PostOrderWithoutRecusion(BTNode<T> *r)//后序遍历(非递归)
{
stack<BTNode<T>*> NodeStack;
BTNode<T> *pre,*p;
pre=p=r;
while(p)
{
for(;p->lChild;p=p->lChild)
NodeStack.push(p);
while (p&&(!p->rChild||p->rChild==pre))//没有右孩子或者右孩子刚被访问过
{
//...访问p指针指向的结点
//深度优先输出树
cout<<p->data<<' ';
if(NodeStack.empty())
return true;
pre=p;
p=NodeStack.top();
NodeStack.pop();
}
NodeStack.push(p);
p=p->rChild;//转向右孩子
}
return true;
}
template <class T>
void BT<T>:: Display()
{
//cout<<"进行到这里了,且root为"<<root<<endl;
RecDisplay(root);
cout<<endl;
}
template <class T>
void BT<T>:: RecDisplay(BTNode<T> *t)
{
if(t!=NULL)
{
cout<<t->data;
if(t->lChild||t->rChild)
{
cout<<'(';
RecDisplay(t->lChild);
cout<<',';
if(t->rChild)
RecDisplay(t->rChild);
else
cout<<'#';
cout<<')';
}
}
else
{
cout<<'#';
}
}
int main()
{
BT<char> Tree;
Tree.NewTree();
Tree.Display();
cout<<"广度优先遍历如下"<<endl;
Tree.LevelOrder(Tree.GetRoot());
cout<<endl<<"前序遍历如下(递归)"<<endl;
Tree.PreOrder(Tree.GetRoot());
cout<<endl<<"前序遍历如下(非递归)"<<endl;
Tree.PreOrderWithoutRecusion(Tree.GetRoot());
cout<<endl<<"中序遍历如下(递归)"<<endl;
Tree.InOrder(Tree.GetRoot());
cout<<endl<<"中序遍历如下(非递归)"<<endl;
Tree.InOrderWithoutRecusion(Tree.GetRoot());
cout<<endl<<"后序遍历如下(递归)"<<endl;
Tree.PostOrder(Tree.GetRoot());
cout<<endl<<"后序遍历如下(非递归)"<<endl;
Tree.PostOrderWithoutRecusion(Tree.GetRoot());
cout<<endl;
cout<<"前序序列为:";
string a="ABCDEGF";
cout<<a<<endl;
cout<<"中序序列为:";
string b="CBEGDFA";
cout<<b<<endl;
cout<<"现在按前序、中序序列构造二叉树如下:"<<endl;
Tree.PreInCreateTree(a,b);
Tree.Display();
cout<<"后序序列为:";
string c="CGEFDBA";
cout<<c<<endl;
cout<<"中序序列为:";
string d="CBEGDFA";
cout<<d<<endl;
cout<<"现在按后序、中序序列构造二叉树如下:"<<endl;
Tree.PostInCreateTree(c,d);
Tree.Display();
return 0;
}
以下为按要求输入后,所得到的输出情况:
本人为在校学生,仅仅为了记录学习历程,算法不当或过于低级请谅解,也欢迎大家指出其中的错误,啦啦啦 >_<