这里实现了二叉树类的一些基本功能,比如前中后序遍历,层次序遍历,并且可以用前序遍历和中序遍历构建二叉树。
ps:开发环境为vs2010
二叉树类头文件:
#pragma once
class btree
{
public:
struct treenode{
//树节点的数据域
char data;
//树节点的左右子树指针
treenode*left,*right;
}*root;//根结点
btree(void);//构造函数
btree(char pre[],char inn[],int flag);//构造函数重载
//析构函数
~btree(void);
//复制构造函数
btree(btree &s);
//逐层输入构造二叉树
treenode* create(char start[],int n,int pos);
void provisit();//前序遍历
void provisit(treenode*cur);//重载前序遍历
void invisit();//中序遍历
void invisit(treenode*cur);//重载中序遍历
void postvisit();//后序遍历
void postvisit(treenode*cur);//重载后序遍历
void levelorder();//层序遍历
void levelorder(treenode*cur);//重载层序遍历
void destory(treenode*cur);//删除结点指向的子树
void creattree(int flag);//二叉树构建函数
//用先序遍历和中序遍历构造子树
treenode* creatree(char pre[],int prelength,char in[]);
//复制该节点指向的子树
treenode* copytree(treenode *c);
};
类实现源文件:
#include "StdAfx.h"
#include "btree.h"
//#include "queue.h"
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
//********************************************************************************
//函数名:btree
//函数参数:void
//函数返回类型:
//函数功能:构造函数
//备注:默认构造函数,只把根节点置空
//********************************************************************************
btree::btree(void)
{
root=NULL;//根节点置空
}
//********************************************************************************
//函数名:btree
//函数参数:char pre[],char inn[]分别是先序遍历和中序遍历的字符串数组
//函数返回类型:
//函数功能:当参数flag为1时,用先序遍历和中序遍历构造二叉树;为2时,采用后序遍历和中序遍历建立
//备注:这是类型1的构造函数实现
//********************************************************************************
btree::btree(char pre[],char inn[],int flag)
{
if(flag==1)
root=creatree(pre,strlen(pre),inn);//调用函数进行初始化
if(flag==2){}//没有要求具体实现所以省略
}
//********************************************************************************
//函数名:~btree
//函数参数:无
//函数返回类型:
//函数功能:析构函数
//备注:调用删除子树的函数从根节点开始删除
//********************************************************************************
btree::~btree(void)
{
destory(root);//调用节点删除函数进行析构
}
//********************************************************************************
//函数名:btree
//函数参数:btree&s 另一个btree类的对象
//函数返回类型:
//函数功能:复制构造函数
//备注:调用复制子树的函数从根节点开始复制
//********************************************************************************
btree::btree(btree &s)
{
root=copytree(s.root);//调用子树复制函数进行复制构造过程
}
//********************************************************************************
//函数名:cpoytree
//函数参数:treenode*c 指向树节点的指针
//函数返回类型:treenode*
//函数功能:复制c指向的子树
//备注:c子树不为空
//********************************************************************************
btree::treenode* btree::copytree(treenode *cc)
{
//如果该子树为空,返回空指针
if(cc==NULL)
return NULL;
//建立当前节点
treenode *cur;
cur=new treenode;
cur->data=cc->data;
//当左子树为空,直接置空
if(cc->left==NULL)
cur->left=NULL;
//否则递归建立左子树
else cur->left=copytree(cc->left);
//右子树过程与左子树相同
if(cc->right==NULL)
cur->right=NULL;
else cur->right=copytree(cc->right);
//返回新建立节点的指针
return cur;
}
//********************************************************************************
//函数名:destory
//函数参数:treenode*cur
//函数返回类型:无
//函数功能:删除该节点指向的子树
//备注:无
//********************************************************************************
void btree::destory(treenode*cur)
{
//如果左子树不为空,则递归删除左子树,最后把左子树置空
if(cur->left!=NULL)
{
destory(cur->left);
cur->left=NULL;
}
//右子树处理类似左子树
if(cur->right!=NULL)
{
destory(cur->right);
cur->right=NULL;
}
//删除当前节点
delete cur;
}
//********************************************************************************
//函数名:create
//函数参数:char start【】,int n,int pos
//函数返回类型:treenode*
//函数功能:把数组start的字符按照层次序输入到二叉树中
//备注:无
//********************************************************************************
btree::treenode* btree::create(char start[],int n,int pos)
{
treenode*rot;
if(n>pos)
{
rot=new treenode;
rot->data=start[pos-1];//建立当前节点
//按照完全二叉树建立左右子树
rot->right=create(start,n,2*pos+1);
rot->left=create(start,n,2*pos);
return rot;
}
else return NULL;
}
//********************************************************************************
//函数名:provisit
//函数参数:无
//函数返回类型:无
//函数功能:实现整棵树的先序遍历
//备注:调用其重载函数实现
//********************************************************************************
void btree::provisit()
{
provisit(root);//调用重载函数
cout<<endl;
}
//********************************************************************************
//函数名:provisit
//函数参数:treenode*cur
//函数返回类型:无
//函数功能:实现某节点开始的先序遍历
//备注:无
//********************************************************************************
void btree::provisit(treenode*cur)
{
if(cur!=NULL)
{cout<<cur->data<<' ';
provisit(cur->left);
provisit(cur->right);}
}
//********************************************************************************
//函数名:invisit
//函数参数:无
//函数返回类型:无
//函数功能:实现整棵树的中序遍历
//备注:调用其重载函数实现
//********************************************************************************
void btree::invisit()
{
invisit(root);//调用重载函数
cout<<endl;
}
//********************************************************************************
//函数名:invisit
//函数参数:treenode*cur
//函数返回类型:无
//函数功能:实现某节点开始的中序遍历
//备注:无
//********************************************************************************
void btree::invisit(treenode*cur)
{
if(cur!=NULL){
invisit(cur->left);
cout<<cur->data<<' ';
invisit(cur->right);}
}
//********************************************************************************
//函数名:postvisit
//函数参数:无
//函数返回类型:无
//函数功能:实现整棵树的后序遍历
//备注:调用其重载函数实现
//********************************************************************************
void btree::postvisit()
{
postvisit(root);//调用重载函数
cout<<endl;
}
//********************************************************************************
//函数名:postvisit
//函数参数:treenode*cur
//函数返回类型:无
//函数功能:实现某节点开始的后序遍历
//备注:无
//********************************************************************************
void btree::postvisit(treenode*cur)
{
if(cur!=NULL)
{
postvisit(cur->left);
postvisit(cur->right);
cout<<cur->data<<' ';}
}
//********************************************************************************
//函数名:levelorder
//函数参数:无
//函数返回类型:无
//函数功能:实现某节点开始的层次遍历
//备注:无
//********************************************************************************
void btree::levelorder()
{
levelorder(root);//调用重载函数
cout<<endl;
}
//********************************************************************************
//函数名:levelorder
//函数参数:treenode*cur
//函数返回类型:无
//函数功能:实现某节点开始的层次遍历
//备注:无
//********************************************************************************
void btree::levelorder(treenode*cur)
{
treenode*pp=cur;
//利用循环队列实现
int r=0,l=0;
treenode*queue[100];
queue[0]=cur;//第一个进入
r++;//右端右移一
while(l<r)//当队列不为空
{
pp=queue[l%100];//保存队列首个元素
cout<<queue[l%100]->data<<' ';//输出
l++;//左端出队
if(pp->left!=NULL)
{
queue[r%100]=pp->left;//左子树进队
r++;
}
if(pp->right!=NULL)
{
queue[r%100]=pp->right;//右子树进队
r++;
}
}
}
//********************************************************************************
//函数名:creattree
//函数参数:int flag
//函数返回类型:无
//函数功能:作为普通的成员函数,按照第一种类型构造二叉树
//备注:无
//********************************************************************************
void btree::creattree(int flag)
{
//作为普通成员函数,和构造函数区别,过程一样
if(flag==1)
{
char pre[1000]={'\0'},inn[1000]={'\0'};
cout<<"请输入先序遍历"<<endl;
cin>>pre;
cout<<"请输入中序遍历"<<endl;
cin>>inn;
root=creatree(pre,strlen(pre),inn);
}
}
//********************************************************************************
//函数名:creatree
//函数参数:char *pre,int prelength,char *in,int inlength
//函数返回类型:treenode*
//函数功能:用先序遍历和中序遍历构造二叉树
//备注:无
//********************************************************************************
btree::treenode* btree::creatree(char *pre,int prelength,char *inn)
{
if(prelength<=0) return NULL;//如果当前数组长度为0,即已经构造完成,则返回NULL
if(pre[0]=='\0')return NULL;//如果当前数组第一个元素也是空,同样表明构造完成
//建立当前节点,赋值data,左右子树指针
treenode *newnode;
newnode=new treenode;
newnode->data=*pre;
newnode->left=NULL;
newnode->right=NULL;
//在中序遍历中找到前序遍历的第一个字符
int i;
for(i=0;i<=prelength;i++)
{
if(inn[i]==*pre)
{
break;//找到之后退出
}
}
//对于中序遍历,把当前对应的先序遍历的第一个元素作为划分标准分为左子树和右子树,并把前序遍历中和中序遍历左子树对应的部分一同作为左子树构建参数
//剩余部分作为右子树参数
//递归建立左子树,并把前序遍历和中序遍历做相应的处理
newnode->left=creatree(pre+1,i,inn);
//递归建立右子树,并把前序遍历和中序遍历做相应的处理
//前序遍历从原遍历的i+1个开始,中序遍历从找到位置之后一个开始
newnode->right=creatree(pre+1+i,prelength-1-i,inn+i+1);
//返回当前节点指针
return newnode;
}
测试程序:
// test6.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "btree.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//pre,inn分别存储先序遍历和中序遍历
char pre[1000]={'\0'},inn[1000]={'\0'};
cout<<"请按顺序输入先序遍历和中序遍历"<<endl;
cin>>pre;//输入先序遍历
cin>>inn;//输入中序遍历
//构造函数类型1初始化二叉树
//初始化的数据来自先序遍历和中序遍历
btree test(pre,inn,1);
cout<<"分别为先序、中序、后序、层次序遍历"<<endl;
test.provisit();//实现先序遍历
test.invisit();//中序遍历
test.postvisit();//后序遍历
test.levelorder();//层次序遍历
cout<<"******************************"<<endl;
//复制构函数初始化第二个二叉树对象
btree test1(test);
cout<<"分别为先序、中序、后序、层次序遍历"<<endl;
test1.provisit();//实现先序遍历
test1.invisit();//中序遍历
test1.postvisit();//后序遍历
test1.levelorder();//层次序遍历
system("pause");
return 0;
}