//链表描述二叉树的创建与遍历
#include <iostream>
using namespace std;
/**********************************/
/*以下内容是一个队列数据结构的定义*/
/*队列引入是为实现二叉树的逐层遍历*/
/**********************************/
template <class T>
class Node{
public:
T data;
Node<T> *link;
};
//FIIFO对象
template <class T>
class LinkedQueue{
public:
LinkedQueue(){front=rear=0;}
~LinkedQueue();
bool IsEmpty()const{return ((front)?false:true);}
bool IsFull()const;
T First()const; //返回队首元素
T Last()const; //返回队尾元素
LinkedQueue<T>& Add(const T& x);
LinkedQueue<T>& Delete(T& x);
void Output();
Node<T> *front; //指向第一个节点
Node<T> *rear; //最后一个节点
};
template <class T>
LinkedQueue<T>::~LinkedQueue(){
Node<T> *next;
while (front){
next = front->link;
delete front;
front = next;
}
}
class OutOfBounds{
public:
OutOfBounds(){
//cout<<"Out Of Bounds!"<<endl;
}
};
//内存不足的异常类
class NoMem{
public:
NoMem(){
cout<<"No Memory!"<<endl;
}
};
//该队列的输出方法
template<class T>
void LinkedQueue<T>::Output(){
Node<T> *temp = front;
while(temp){
cout<<temp->data<<" ";
temp=temp->link;
}
cout<<""<<endl;
}
//判断当前队列是否已满
template <class T>
bool LinkedQueue<T>::IsFull()const{
Node<T>*p;
try{
p = new Node<T>;
delete p;
return false;
}
catch (NoMem)
{
return true;
}
}
//返回队列的第一个元素
template <class T>
T LinkedQueue<T>::First()const{
if(IsEmpty())
throw OutOfBounds();
return front->data
}
//返回队列的最后一个元素
template <class T>
T LinkedQueue<T>::Last()const{
if(IsEmpty())
throw OutOfBounds();
return rear->data
}
//将x添加到队列的尾部
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T&x){
Node<T>*p = new Node<T>;
p->data=x;
p->link=0;
//在队列尾部添加新节点
if (front){
rear->link = p;
}
else{
front=p;
}
rear=p;
return *this;
}
//删除第一个元素并将其放到X中去
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T&x){
if (IsEmpty()){
throw OutOfBounds();
}
x = front->data;
Node<T>*p = front;
front = front->link;
delete p;
return *this;
}
/**********************************/
/*以下内容是一个二叉树数据结构定义*/
/**********************************/
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; //右子树
};
template<class T>
void Visit(BinaryTreeNode<T>*node)
{
cout<<node->data;
}
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 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));
//二叉树类的扩充
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);
};
//取根节点的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)
{
cout<<t->data<<' ';
}
template<class T>
void BinaryTree<T>::PreOutput()
{
PreOrder(Output,root);
cout<<endl;
}
template<class T>
void BinaryTree<T>::InOutput()
{
InOrder(Output,root);
cout<<endl;
}
template<class T>
void BinaryTree<T>::PostOutput()
{
PostOrder(Output,root);
cout<<endl;
}
template<class T>
void BinaryTree<T>::LevelOutput()
{
LevelOrder(Output);
cout<<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);
}
}
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);
}
}
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);
}
}
template<class T>
void BinaryTree<T>::LevelOrder(void(*Visit)(BinaryTreeNode<T>*u))
{
LinkedQueue<BinaryTreeNode<T>*>myQueue;
BinaryTreeNode<T>*t;
t=root;
while(t)
{
Visit(t);
if(t->LeftChild)
myQueue.Add(t->LeftChild);
if(t->RightChild)
myQueue.Add(t->RightChild);
if(!myQueue.IsEmpty())
{
myQueue.Delete(t); //队列中删除一个节点并且将其赋值给t
}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 ;
}
cout<<"Root:"<<root->data<<endl;
BinaryTreeNode<T> *newNode = new BinaryTreeNode<T>;
newNode->data = u;
LinkedQueue<BinaryTreeNode<T>*>myQueue;
BinaryTreeNode<T>*t;
t=root;
while(t)
{
cout<<"t.data="<<t->data<<endl;
if(t->LeftChild){
myQueue.Add(t->LeftChild);
cout<<"Left is"<<t->LeftChild->data<<endl;
}
if(t->RightChild){
myQueue.Add(t->RightChild);
cout<<"Right is"<<t->RightChild->data<<endl;
}
if(!t->LeftChild)
{
cout<<"Put "<<newNode->data<<" in Left"<<endl;
t->LeftChild=newNode;
return;
}else{
cout<<"t.Leftdata="<<t->LeftChild->data<<endl;
}
if(!t->RightChild)
{
cout<<"Put "<<newNode->data<<" in Right"<<endl;
t->RightChild=newNode;
return;
}else{
cout<<"t.Rightdata="<<t->RightChild->data<<endl;
}
if(!myQueue.IsEmpty())
{
myQueue.Delete(t); //队列中删除一个节点并且将其赋值给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<int> a,x,y,z;
template<class T>
void countTree(BinaryTreeNode<T>*t)
{
count++;
}
void main()
{
cout<<"请逐层从左往右输入每一个元素,输入后回车,按0结束输入"<<endl;
int myInput = 0;
while(true)
{
cin>>myInput;
if(myInput==0)
{
break;
}else{
y.AddNode(myInput);
}
}
cout<<"前序排列:"<<endl;
y.PreOutput();
cout<<"中序排列:"<<endl;
y.InOutput();
cout<<"后序排列:"<<endl;
y.PostOutput();
cout<<"逐层排列:"<<endl;
y.LevelOutput();
cout<<"树的高度:"<<endl;
cout<<y.Height(y.root)<<endl;
cout<<"节点数目:"<<endl;
cout<<y.Size()<<endl;
}
[C++]数据结构:链表二叉树的创建与四种遍历方式
最新推荐文章于 2022-08-22 14:51:31 发布
这篇博客介绍了如何使用链表来描述二叉树,并详细讲解了二叉树的前序、中序、后序遍历以及层次遍历的方法。此外,还提供了队列数据结构的实现,用于层次遍历。
摘要由CSDN通过智能技术生成