您的位置:首页 > 理论基础 > 数据结构算法

[C++]数据结构:链表二叉树的创建与四种遍历方式

2012-11-29 18:08 781 查看
//链表描述二叉树的创建与遍历
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: