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

这篇博客介绍了如何使用链表来描述二叉树,并详细讲解了二叉树的前序、中序、后序遍历以及层次遍历的方法。此外,还提供了队列数据结构的实现,用于层次遍历。
摘要由CSDN通过智能技术生成
//链表描述二叉树的创建与遍历
#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值