[C++]数据结构实验05:二叉树的遍历

这篇博客详细介绍了如何用C++实现二叉树的遍历,包括前序遍历、中序遍历、后序遍历以及层次遍历。同时,还涵盖了如何根据前序和中序序列构建二叉树,并输出相应的后序序列。博客内容包括了二叉树节点的定义、链表描述二叉树的创建与遍历、以及相关的遍历算法实现,如递归和非递归方法。
摘要由CSDN通过智能技术生成
/*************************************************************/
/*	三、二叉树的遍历
/*	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;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值