⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 binarytree.template

📁 二叉树的数据结构的代码
💻 TEMPLATE
字号:
//****************************************************************************
//访问函数                                                                   *
//作用:其指针作为其他成员函数的参数,将访问的数据分别标准输出和文件输出     *
//****************************************************************************
template <class T>
void BinaryTree<T>::Visit(BinaryTreeNode<T> *node,Inorder select)//在类外定义成员函数时static不能再加上,否则出错
{
	ofstream outfile;
	if(select==RECURSIVEINORDER)
			outfile.open("recursiveInorder.dat",ios::app);
	//输入输出方式app:以输出方式打开文件,文件指针指向文件末尾,这在递归调用时尤为重要,使得在每次递归写入的数据不会丢失
	else
		outfile.open("nonrecursiveInorder.dat",ios::app);
		if(!outfile)
		{
			cerr<<"open error!"<<endl;
			exit(1);
		}
		outfile<<node->data<<" ";
		cout<<node->data<<" ";
		outfile.close();
}
//***************************************************************************************
//建树函数                                                                              *
//作用:根据私有数据成员str_pre构造二叉树,只在构造函数BinaryTree(char *s)中调用了此函数*
//***************************************************************************************
template <class T>
inline BinaryTreeNode<T> *BinaryTree<T>::MakeTree() 
{ 
	BinaryTreeNode<T> *r;
	char element;
            
	element=str_pre[counter++];
		
    if(element=='#')
	{ 
		r=NULL; 
    }
	else
	{ 
		r=new BinaryTreeNode<T>;
        r->data=element; 
        r->leftchild=MakeTree(); 
        r->rightchild=MakeTree(); 
	} 
	return r;                   
}
//****************************************************************************************
//毁树函数                                                                               *
//作用:销毁以参数作为根结点的二叉树,本程序只在析构函数BinaryTree(char *s)中调用了此函数*
//****************************************************************************************
template <class T>
inline void BinaryTree<T>::destroy(BinaryTreeNode<T> *current) 
{ 
	if(current!=NULL)
	{ 
		destroy(current->leftchild); 
		destroy(current->rightchild); 
		delete current; 
	} 
} 
//***************************************************************************************
//中序递归遍历二叉树函数                                                                *
//作用:使用递归法中序遍历二叉树                                                        *
//***************************************************************************************
template <class T>
void BinaryTree<T>::recursiveInorder()
{
	ofstream outfile;
	outfile.open("recursiveInorder.dat",ios::trunc);
	//输入输出方式trunc:打开一个文件,如果文件存在,则删除其中全部数据,如果文件不存在,则建立新文件
	//如果指定了ios::out方式,而未指定ios::app,iso::ate,iso::in,则同时默认此方式
	//由于在Visit函数中的输入输出方式是iso::app,不会在执行recursiveInorder()函数时将文件清空,所以这里要显示清空文件内容
	outfile.close();
	recursiveInorder(Visit,root);
}
//***************************************************************************************
//中序非递归遍历二叉树函数                                                              *
//作用:利用栈实现中序遍历二叉树的非递归算法                                            *
//***************************************************************************************
template <class T>
void BinaryTree<T>::nonrecursiveInorder()
{
	ofstream outfile;
	outfile.open("nonrecursiveInorder.dat",ios::trunc);
	outfile.close();
	nonrecursiveInorder(Visit,root);
}
//***************************************************************************************
//搜索函数                                                                              *
//作用:搜索序列中是否存在指定字符,存在返回字符下标,不存在返回-1                      *
//***************************************************************************************
template <class T>
int BinaryTree<T>::searchchar(char c,char *order)
{
	for(int i=0;i!=strlen(order);i++)
	{
		if(c==order[i])
			return i;
	}
	return -1;
}
//***************************************************************************************
//中序递归遍历二叉树函数                                                                *
//作用:使用递归法中序遍历二叉树                                                        *
//***************************************************************************************
template <class T>
inline void BinaryTree<T>::recursiveInorder(void(*Visit)(BinaryTreeNode<T> *node,Inorder select),BinaryTreeNode<T> *t)
{
	if(t)
	{
		recursiveInorder(Visit,t->leftchild);
        Visit(t,RECURSIVEINORDER);
        recursiveInorder(Visit,t->rightchild);
	}
}
//***************************************************************************************
//中序非递归遍历二叉树函数                                                              *
//作用:利用栈实现中序遍历二叉树的非递归算法                                            *
//***************************************************************************************
template <class T>
void BinaryTree<T>::nonrecursiveInorder(void(*Visit)(BinaryTreeNode<T> *node,Inorder select),BinaryTreeNode<T> *t)
{
	stack<BinaryTreeNode<T> *> tempstack;
	BinaryTreeNode<T> *pointer=t;
	while(!tempstack.empty()||pointer)
	{
		if(pointer)
		{
			tempstack.push(pointer);
		    pointer=pointer->leftchild;
		}
		else
		{
			pointer=tempstack.top();
			Visit(pointer,NONRECURSIVEINORDER);
			pointer=pointer->rightchild;
            tempstack.pop();
		}
	}
}
//*****************************************************************************************************
//造树函数                                                                                            *
//作用:根据前序序列和后续序列构造二叉树,本程序只在构造函数BinaryTree(char *p, char *s)中调用了此函数*
//*****************************************************************************************************
template <class T>
inline  BinaryTreeNode<T>* BinaryTree<T>::CreateTree(char *pre,char *in)
{
	char c=pre[0];
    char *temppre=new char[MAX_BINARYTREE_SIZE];
    char *tempin=new char[MAX_BINARYTREE_SIZE];
    char *p;
    int i=0; 
    BinaryTreeNode<T>* bnode=NULL;

    if(pre=='\0')
		return NULL;
	/*内存初始化函数memset()用法详解
	作用:在一段内存中填充某个给定的值,注意填充时是按照字节顺序填充的,而不是按照元素填充。
	此方法是对较大的结构体和数组进行清零操作的一种有效方法。
	函数形式:memset(void *buffer,int c,size_t n)
	在头文件cstring或string.h或memory.h中
	buffer是需要设置的内存的开始地址;c是期望填充值;n是需要填充的字节数。*/
	memset(temppre,0,MAX_BINARYTREE_SIZE);
	memset(tempin,0,MAX_BINARYTREE_SIZE);

	bnode=new BinaryTreeNode<T>(c);
	i=searchchar(pre[0],in);
	if(i==-1)
		return 0;
    p=in;
	strncpy(tempin,p,i);//如果找到,则将中序序列的前i个元素复制给tempin,此时tempin存放的是根结点左子树的节点元素的中序序列
	p=pre;
	strncpy(temppre,p+1,i);//将前序序列第二个元素后的前i个元素复制给temppre,此时temppre存放的根节点左子树结点元素的前序序列
	bnode->leftchild=CreateTree(temppre,tempin);//递归调用CreateTree函数构造当前结点的左子树

    memset(tempin,0,MAX_BINARYTREE_SIZE);//将tempin和temppre中的元素重新置为0
    memset(temppre,0,MAX_BINARYTREE_SIZE);

    p=in+i+1;//p指向前序序列第i+1个元素,此时,p是根结点右子树的基地址
	strncpy(tempin,p,strlen(in)-i);//将根结点的右子树的中序序列复制给tempin
	p=pre+i+1;//p指向前序序列第i+1个元素,此时,p是根结点右子树的基地址
	strncpy(temppre,p,strlen(in)-i);//将根结点的右子树的前序序列复制给tempin
	bnode->rightchild=CreateTree(temppre,tempin);//递归调用CreateTree函数构造当前结点的右子树
	delete [] temppre;
	delete [] tempin;
	return bnode;
}
//************************************************************************************************************
//测试算法结果函数                                                                                           *
//作用:测试两个遍历算法recursiveInorder和nonrecursiveInorder结果是否相同。如果相同,返回true, 否则返回false *
//************************************************************************************************************
template <class T>
bool BinaryTree<T>::testTraverse()
{
	char ch1=' ',ch2=' ';
	int flag=0;
	ifstream infile_recursiveInorder("recursiveInorder.dat");
	ifstream infile_nonrecursiveInorder("nonrecursiveInorder.dat");
	if(!infile_recursiveInorder)
	{
		cerr<<"open \"recursiveInorder.dat\" error!"<<endl;
		exit(1);
	}
	if(!infile_nonrecursiveInorder)
	{
		cerr<<"open \"nonrecursiveInorder.dat\" error!"<<endl;
		exit(1);
	}
	while(infile_recursiveInorder.get(ch1)&&infile_nonrecursiveInorder.get(ch2))
	{
		if(ch1!=ch2)
			flag++;
	}
	infile_recursiveInorder.close();
	infile_nonrecursiveInorder.close();
	if(flag==0)
		return true;
    else
		return false;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -