二叉树的构建与遍历,二叉树元素的排序

版权声明:如需转载,请联系原作者授权... https://blog.csdn.net/Superman___007/article/details/82382563

   构建二叉树 , 定义一个节点空间 , 一个数据域 , 和左右节点域 , 并先序遍历一次树 .

#include<iostream>
using namespace std;
//前置声明
class tree;
//节点:
class node
{
public:
	friend class tree;
	node(char);
protected:
	char data;//数据域
	node* lchild;//指向左孩子
	node* rchild;//指向右孩子 
};

node::node(char d):data(d),lchild(NULL),rchild(NULL)
{
}

//构造树
class tree
{
public:
	tree();
	bool createTree(char*&,node*&);//地址  地址变量引用
	node*& getRoot();//定义公有接口
	//遍历 前序  中序   后序
	//前序
	void preOrder(node*);
	//void inOrder();	//中序
	//void postOrder();	//后序
protected:
	node* root;			//根节点---堆区
};

//前序遍历
void tree::preOrder(node* ploc)
{
	if(NULL==ploc)
		return;
	cout<<ploc->data<<" ";
	preOrder(ploc->lchild);
	preOrder(ploc->rchild);
}

node*& tree::getRoot()
{
		return this->root;
}

tree::tree():root(NULL)
{
}

//前序创建树
bool tree::createTree(char*& d,node* & ploc)        //为什么不能用  char d[] 来传递树的数据?
{
	if('\0'==*d)
		return true;        //递归需要停止的条件,当遇到'\0'的时候停止
	//分配节点
	if('#'==*d)             //当传递过来的是'#' 元素,则将子节点赋值为NULL
		ploc=NULL;
	else
	{
		ploc=new node(*d);	//new 对象---构造器分配空间    new一个节点当作根节点用,所以直接将根节点传递过来,用来root的别名,所以node* & ploc
		if(NULL==ploc)
			return false;
		//修改指向域
		createTree(++d,ploc->lchild);        //通过递归来构建下一个子节点
		createTree(++d,ploc->rchild);
		return true;
	}
}
                                         //先序构建二叉树
void main()                              //        a
{                                        //    #         b
	char* buf="a#bc##d##";           //          c        d
	//实例化                          //        #   #    #   #
	tree t;//构造器
	t.createTree(buf,t.getRoot());
	t.preOrder(t.getRoot());	//先序遍历
}

关于  bool tree::createTree(char*& d,node* & ploc) 的 char*&  d 传递树元素的讲解 .

   实现树的先序遍历 , 实现中序遍历 , 实现后序遍历 , 实现查找树的元素 , 实现修改树的元素 .

#include<iostream>
using namespace std;
//前置声明
class tree;
//节点:
class node
{
public:
	friend class tree;
	node(char);
protected:
	char data;//数据域
	node* lchild;//指向左孩子
	node* rchild;//指向右孩子 
};
node::node(char d):data(d),lchild(NULL),rchild(NULL){}

//树
class tree
{
public:
	tree();
	bool createTree(char*&,node*&);//地址  地址变量引用
	node*& getRoot();//定义公有接口
	//遍历 前序  中序   后序
	//前序:
	void preOrder(node*);//前序
	void inOrder(node*);//中序
	void postOrder(node*);//后序
	//查找
	node* find(node*,char);
	node* match(char key,node* ploc);//判断ploc节点是否在存在key值
	bool alter(char key,node* ploc,char vaule);//修改
protected:
	node* root;//根节点---堆区
};

tree::tree():root(NULL)
{
}

//判断ploc节点是否存在key值,存在返回该节点地址  不存在则遍历查找
node* tree::match(char key,node* ploc)
{
	node* result=NULL;	

	if(NULL==ploc)
		return NULL;
	if(key==ploc->data)
		return ploc;
	
	//左子树
	result=match(key,ploc->lchild); //返回地址 或  NULL
	if(result!=NULL)
		return result;
	//右子树
	return match(key,ploc->rchild);
}	

//修改
bool tree:: alter(char key,node* ploc,char value)
{
	node* result=NULL;
	result=this->match(key,ploc);
	if(NULL!=result)
	{
		result->data=value;
		return true;
	}
	else	
		return false;
}

//查找 
node* tree:: find(node* ploc,char key)
{
	node* result=NULL;
	if(NULL==ploc)
		return result;
	if(ploc->data==key)
		return ploc;
	//左子树
	if(NULL!=(result=find(ploc->lchild,key)))
		return result;
	//右子树
	if(NULL!=(result=find(ploc->rchild,key)))
		return result;
}

//前序遍历:每次调用函数时只打印当前节点信息,左子树/右子树交给下一次函数来打印
void tree::preOrder(node* ploc)
{
	if(NULL==ploc)
		return;
	//只打印ploc节点的信息
	cout<<ploc->data<<" ";
	//左子树的节点
	preOrder(ploc->lchild);//递归打印左子树的节点
	preOrder(ploc->rchild);//递归打印右子树的节点
}

//前序创建树
bool tree::createTree(char* &d,node* &ploc)
{
	if('\0'==*d)
		return true;
//1分配节点空间
	if('#'==*d)//当前节点为空节点
		ploc=NULL;
	else
	{
		ploc=new node(*d);//new对象---由构造器分配空间
		if(NULL==ploc)
			return false;
//2修改指针向域
		createTree(++d,ploc->lchild);//当前节点的左子树	
		createTree(++d,ploc->rchild);//当前节点的右子树
		return true;
	}
}

void tree:: postOrder(node* ploc)//后序
{
	if(NULL==ploc)
		return;
	//遍历左子树
	postOrder(ploc->lchild);
	//遍历右子树
	postOrder(ploc->rchild);
	//访问当前节点
	cout<<ploc->data<<" ";
}

void tree::inOrder(node* ploc)
{
	if(NULL==ploc)
		return;
	//遍历左子树
	inOrder(ploc->lchild);
	//打印当前节点
	cout<<ploc->data<<" ";
	//遍历右子树
	inOrder(ploc->rchild);
}

node* &tree::getRoot()
{
	return this->root;
}

int main()
{
	char *buf="a#bc##d##"; 
//实例化
	tree t;//构造器
	t.createTree(buf,t.getRoot());
	t.preOrder(t.getRoot());
	cout<<endl;
	t.inOrder(t.getRoot());
	cout<<endl;
	t.postOrder(t.getRoot());
	cout<<endl;
		
	if(NULL!=t.match('c',t.getRoot()))
		cout<<"查找成功"<<endl;
	else
		cout<<"查找失败"<<endl;

	t.alter('c',t.getRoot(),'Y');
	t.preOrder(t.getRoot());
	cout<<endl;
}

   二叉树的查找,插入,中序遍历排序 .

#include<iostream>
using namespace std;
template<typename T1>
class sortTree;
//根的类型
template<typename T>
class node
{
public:
	//有参构造
	node(T);
	//友元类
	friend class sortTree<T>;
protected:
	T data;    //数据域
	node* lchild;//左孩子
	node* rchild;//右孩子
};
//有参构造
template<typename T>
node<T>::node(T k):data(k),lchild(NULL),rchild(NULL)
{
}

template<typename T1>
class sortTree
{
public:
	sortTree();
	sortTree(T1*,int);
	//定义接口:查找指定插入位置
	bool SearchTN(node<T1>* ploc,node<T1>** pos,int key,node<T1>*);
	//插入节点
	bool InsertTN(int key,node<T1>* ploc);
	//中序
	void inOrder(node<T1>* ploc);
	//接口
	node<T1>* getRoot();
protected:
	//根节点
	node<T1>* root;	
};
//构造函数
template<typename T1>
sortTree<T1>::sortTree(T1* data,int ilen):root(NULL)
{
	int i=0;
	while(i<ilen)
	{
		//cout<<*(data+i)<<endl;
		this->InsertTN(*(data+i),this->root);//构造成排序树
		i++;
	}	
}
template<typename T1>
//无参构造
sortTree<T1>::sortTree():root(NULL)
{
}
//查找节点
template<typename T1>
bool sortTree<T1>::SearchTN(node<T1>* ploc,node<T1>** pos,int key,node<T1>* fn)
{
	if(NULL==ploc)	//查找失败
	{
		*pos=fn;//记录父节点地址
		return false;
	}
	else if(key==ploc->data)//
	{
		*pos=ploc;//记录查找成功的地址
		return true;
	}
	else if(key > ploc->data)//右边
		return SearchTN(ploc->rchild,pos,key,ploc);
	else
		return SearchTN(ploc->lchild,pos,key,ploc);
}
//插入节点
template<typename T1>
bool sortTree<T1>::InsertTN(int key,node<T1>* ploc)
{
//1分配空间
	node<T1>* pnew=new node<T1>(key);
	if(NULL==pnew)
		return false;
//2修改指向域---查找节点位置
	node<T1>* pos=NULL;
	if(false==this->SearchTN(this->root,&pos,key,NULL))
	{
		if(NULL==pos)//说明Pnew成为根节点
			this->root=pnew;
		else
		{
			if(key<pos->data)//成为左孩子
			{
				pos->lchild=pnew;
			}
			else		//成为右孩子
				pos->rchild=pnew;
		}
		return true;
	}
}
template<typename T1>
void sortTree<T1>::inOrder(node<T1>* ploc)
{
	if(NULL==ploc)
		return ;
	//左子树
	inOrder(ploc->lchild);
	cout<<ploc->data<<" ";
	//右子树
	inOrder(ploc->rchild);
	
}
template<typename T1>
node<T1>* sortTree<T1>:: getRoot()
{	
	return this->root;
}

int main()
{
//实例化:
	int b[]={10,1,0,8,3,5,4,6,7,12,11,30,28,27,26};
	sortTree<int> s(b,15);//有参构造
	s.inOrder(s.getRoot());
}

猜你喜欢

转载自blog.csdn.net/Superman___007/article/details/82382563