zoukankan      html  css  js  c++  java
  • 二叉搜索树的相关功能的实现

    二叉搜索树

    二叉搜索树实现了以下功能
    1.计算二叉搜索树的大小
    2.前中后递归遍历二叉搜索树
    3.前中后非递归遍历二叉搜索树
    4.层序遍历二叉搜索树
    5.二叉搜索树叶子个数
    6.二叉搜索树的深度
    7.二叉搜索树的结点的度
    8.二叉搜索树的双亲以及左右子女的查找
    9.查找某一节点
    10.插入新的结点
    11.删除某一节点
    12.判断是否为平衡树

    在这里插入图片描述

    定义一个结点结构体

    //定义二叉搜索树的节点结构体
    struct BinaryTreeNode
    {
    	BinaryTreeNode <T>* _left;
    	BinaryTreeNode <T>* _right;
    	T _data;
    	BinaryTreeNode(T &data)
    		:_left(NULL)
    		,_right(NULL)
    		,_data(data)
    	{}
    };
    
    

    封装的相关函数

    class BinarySearchTree
    {
    	private:
    		BinaryTreeNode<T>* _root;
    	public:
    		//无参的构造函数
    		BinarySearchTree()
    		:_root(NULL){}
    		BinarySearchTree(vector<T> v)
    		{
    			_root=NULL;
    			for (int i = 0; i < v.size(); i++)
    			{
    				insert(_root,v[i]);
    			}	
    		}
    		//复制构造函数
    		BinarySearchTree(const BinarySearchTree<T> &s)
    		{_root=CopyBintTree(s.GetRoot());}
    		BinaryTreeNode<T>* GetRoot()
    		{return  this->_root;}
    		//递归先序遍历
    		void PrevOrder(BinaryTreeNode<T>* root);
    		//非递归先序遍历
    		void PrevOrder_NonR();
    		//递归中序遍历二叉树
    		void InOrder(BinaryTreeNode<T>* root);
    		//非递归中序遍历
    		void InOrder_NonR();
    		//递归后续遍历
    		void PostOrder(BinaryTreeNode<T>* root);
    		//非递归后序遍历
    		void PostOrder_NonR();
    		//层序遍历二叉树
    		void Leve1Order();
    		int Size(BinaryTreeNode<T>* root);
    		//二叉搜索树的深度
    		int Depth(BinaryTreeNode<T>* root);
    		//递归求二叉搜索树叶子节点的个数
    		int LeafSize(BinaryTreeNode<T>* root);
    		//求节点的度
    		int DegreeofNode(T tmp);
    		//求节点的层次
    		void level(BinaryTreeNode<T>* root,int val,int &ans,int lev);
    		int GetLevelofNode(T tmp);
    		//二叉搜索树的复制
    		BinaryTreeNode<T>* CopyBintTree(BinaryTreeNode<T>* originNode);
    		//寻找二叉搜索树某一节点的双亲
    		void ParentofNode(BinaryTreeNode<T>* r,T data);
    		//寻找二叉搜索树某一节点的左子女
    		BinaryTreeNode<T>* LeftChildofNode(T tmp);
    		//寻找二叉搜索树某一节点的右子女	
    		BinaryTreeNode<T>* RightChildofNode(T tmp);
    		//查找某一个结点
    		BinaryTreeNode<T>* FindNode(T tmp,BinaryTreeNode<T>* &root);
    		bool insert(BinaryTreeNode<T>* &root, T val);//二叉搜索树的插入一个结点
    		bool Delete(T val);//删除某一个结点
    		bool Search(T x);//二叉搜索树的搜索
    		BinaryTreeNode<T> * Remove(BinaryTreeNode<T> * &root,T val);//二叉搜索树的删除结点
    		bool isBalanced(BinaryTreeNode<T> * &root);//判断是否为平衡二叉树
    		
    };
    

    各个函数的实现

    前中后序遍历的递归实现

    template<class T>
    inline void BinarySearchTree<T>::PrevOrder(BinaryTreeNode<T>* root)
    {		
    	if(root==NULL)
    	return;
    	cout<<root->_data<<" ";
    	PrevOrder(root->_left );
    	PrevOrder(root->_right);
    }
    template<class T>
    inline void BinarySearchTree<T>::InOrder(BinaryTreeNode<T>* root)
    {
    	if(root==NULL)
    		return;
    	InOrder(root->_left );
    	cout<<root->_data <<" ";
    	InOrder(root->_right );
    }
    template<class T>
    inline void BinarySearchTree<T>::PostOrder(BinaryTreeNode<T>* root)
    {
    	if(root!=NULL)
    	{
    		PostOrder(root->_left);
    		PostOrder(root->_right);
    		cout<<root->_data<<" ";
    	}
    }
    

    前中后序遍历的非递归实现

    template<class T>
    inline void BinarySearchTree<T>::PrevOrder_NonR()
    {
    	stack<BinaryTreeNode<T>*> s;
    	BinaryTreeNode<T>* cur=_root;
    	while(cur||!s.empty())
    	{
    		if(cur)
    		{//先将左子树遍历输出后压栈
    		cout<<cur->_data <<" ";
    		s.push(cur);
    		cur=cur->_left;
    		}
    		else{//当左子树为空时开始访问右子树
    		cur=s.top ();
    		s.pop();
    		cur=cur->_right;
    		}
    		}
    }
    template<class T>
    inline void BinarySearchTree<T>::InOrder_NonR()
    {
    	BinaryTreeNode<T>* cur=_root;
    	stack<BinaryTreeNode<T>*> s;
    		while(cur||!s.empty())//cur非空或者栈非空
    		{
    			if(cur)
    			{
    				s.push(cur);//根节点进栈遍历左子树
    				cur=cur->_left;
    			}
    			else
    			{
    				BinaryTreeNode<T>* top=s.top();
    				cout<<top->_data<<" ";
    				s.pop();
    				cur=top->_right;
    			}
    		}
    		cout<<endl;
    }
    template<class T>
    inline void BinarySearchTree<T>::PostOrder_NonR()
    {
    	stack<BinaryTreeNode<T>*> s;
    	BinaryTreeNode<T>* cur=_root;
    	BinaryTreeNode<T>* prev=NULL;//设置标志域
    	s.push(_root);
    	while(!s.empty())
    	{
    		cur=s.top();
    		if((cur->_left ==NULL&&cur->_right ==NULL)
    			||(prev!=NULL&&(prev==cur->_left ||prev ==cur->_right )))
    		{  
    			cout<<cur->_data<<" ";
    			prev=cur;
    			s.pop();
    		}
    		else
    		{
    			if(cur->_right!=NULL)
    			s.push(cur->_right);
    			if(cur->_left!=NULL)
    			s.push(cur->_left); 
    		}
    	}
    
    }
    
    

    层序遍历二叉树

    按层次顺序访问二叉树的处理需要利用一个队列。
    在访问二又树的某一层结点时,把下一层结点指针预先
    记忆在队列中,利用队列安排逐层访问的次序。因此,每
    当访问一个结点时,将它的子女依次加到队列的队尾,然
    后再访问已在队列队头的结点。这样可以实现二叉树结
    点的按层访问

    template<class T>
    inline void BinarySearchTree<T>::Leve1Order()
    {
    	queue<BinaryTreeNode<T>*>q;
    	if(_root!=NULL)
    	{
    		q.push(_root);
    	}
    	while(!q.empty())
    	{
    		BinaryTreeNode<T>* front=q.front();
    		cout<<front->_data <<" ";
    		if(front->_left!=NULL){
    			q.push(front->_left);
    		}
    		if(front->_right!=NULL)
    		q.push(front->_right);
    		q.pop();
    	}
    	cout<<endl;
    }
    
    

    求树的大小

    template<class T>
    inline int BinarySearchTree<T>::Size(BinaryTreeNode<T>* root)
    {
    	static size_t Ssize=0;
    	if(root==NULL)
    		return 0;
    	++Ssize;
    	Size(root->_left);
    	Size(root->_right);
    	return Ssize;
    }
    
    

    求树的深度

    template<class T>
    inline int BinarySearchTree<T>::Depth(BinaryTreeNode<T>* root)
    {	
    	if(root==NULL)
    	return 0;
    	size_t left=Depth(root->_left )+1;
    	size_t right=Depth(root->_right)+1;
    	return (left>right)?left:right;
    }
    

    求树的叶子个数

    template<class T>
    inline int BinarySearchTree<T>::LeafSize(BinaryTreeNode<T>* root)
    {
    	if(root==NULL)
    		return 0;
    	if(root->_left  ==NULL&&root->_right ==NULL)
    	{
    		return 1;
    	}
    	return LeafSize(root->_left )+LeafSize(root->_right );
    }
    
    

    求树的各个结点的度

    利用二叉树的层次遍历方法来统计各个节点的度

    template<class T>
    inline int BinarySearchTree<T>::DegreeofNode(T tmp)
    {
    	queue<BinaryTreeNode<T>*>q;
    		if(_root!=NULL)
    		{
    			q.push(_root);
    		}
    		while(!q.empty())
    		{
    			BinaryTreeNode<T>* cur=q.front();
    			if(cur->_data==tmp){
    				if((cur->_left==NULL&&cur->_right!=NULL)||(cur->_left!=NULL&&cur->_right==NULL))
    				return 1;
    				else if(cur->_left==NULL&&cur->_right==NULL){
    					return 0;
    				}
    				else{
    					return 2;
    				}
    			}
    			if(cur->_left!=NULL){
    				q.push(cur->_left);
    			}
    			if(cur->_right!=NULL)
    			q.push(cur->_right);
    			q.pop();
    		}
    		return -1;
    }
    
    

    复制搜索二叉树

    template<class T>
    inline BinaryTreeNode<T>* BinarySearchTree<T>::CopyBintTree(BinaryTreeNode<T>* originNode)
    {
    	if(originNode==NULL){
    		return NULL;
    	}
    	BinaryTreeNode<T>* temp=new BinaryTreeNode<T>;
    	temp->_data=originNode->_data;
    	temp->_left=CopyBintTree(originNode->_left);
    	temp->_right=CopyBintTree(originNode->_right);
    	return temp;
    }
    

    求某一结点的双亲及左右子女

    template<class T>
    inline void BinarySearchTree<T>::ParentofNode(BinaryTreeNode<T>* r,T data)
    {
    	if(r ==NULL)
    	{
    		return;
    	}
    	if(r->_left != NULL)//当左孩子存在的时候才进行判断,否则程序出错
    	{
    		if(r->_left->_data == data){
    			cout<<"这个节点的双亲结点是:"<<r->_data<<endl;
    		}
    	}
    	if(r->_right != NULL)//如左子树所示
    	{
    		if(r->_right->_data == data)    
    		{
    			cout<<"这个节点的双亲结点是:"<<r->_data<<endl;
    		}
    	}
    	ParentofNode(r->_left,data);		
    	ParentofNode(r->_right,data);
    }
    template<class T>
    inline BinaryTreeNode<T>* BinarySearchTree<T>:: LeftChildofNode(T tmp)
    {
    	queue<BinaryTreeNode<T>*>q;
    	if(_root!=NULL)
    	{
    		q.push(_root);
    	}
    	while(!q.empty())
    	{
    		BinaryTreeNode<T>* cur=q.front();
    		if(cur->_data==tmp&&cur->_left!=NULL){
    			return cur->_left;
    		}
    		if(cur->_left!=NULL){
    			q.push(cur->_left);
    		}
    		if(cur->_right!=NULL)
    		q.push(cur->_right);
    		q.pop();
    	}
    	return NULL;
    }
    template<class T>
    inline BinaryTreeNode<T>* BinarySearchTree<T>::RightChildofNode(T tmp)
    {
    	queue<BinaryTreeNode<T>*>q;
    	if(_root!=NULL)
    	{
    		q.push(_root);
    	}
    	while(!q.empty())
    	{
    		BinaryTreeNode<T>* cur=q.front();
    		if(cur->_data==tmp&&cur->_right!=NULL){
    			return cur->_right;
    		}
    		if(cur->_left!=NULL){
    			q.push(cur->_left);
    		}
    		if(cur->_right!=NULL)
    		q.push(cur->_right);
    		q.pop();
    	}
    	return NULL;
    }
    
    

    求某一结点的层次

    template<class T>
    inline void BinarySearchTree<T>::level(BinaryTreeNode<T>* root,int val,int &ans,int lev)
    {
    	if(NULL==root)
    		ans=-1;
    	else if(root->_data==val)
    		ans=lev;
    	else
    	{
    		level(root->_left,val,ans,lev+1);//在左子树中查找
    		if(ans==-1)
    			level(root->_right,val,ans,lev+1);//在右子树中查找
    		}
    }
    template<class T>
    inline int BinarySearchTree<T>::GetLevelofNode(T tmp)
    {
    	int res=-1;
    	level(_root,tmp,res,1);
    	return res;	
    }
    
    
    

    查找搜索某一个结点

    template<class T>
    inline  BinaryTreeNode<T>* BinarySearchTree<T>::FindNode(T tmp,BinaryTreeNode<T>* &root)
    {
    	if(root==NULL){
    		return NULL;
    	}
    	else if(tmp<root->_data){
    		return FindNode(tmp,root->_left);
    	}
    	else if(tmp>root->_data){
    			return FindNode(tmp,root->_right);
    		}
    	else return root;
    }
    template <class T>
    inline bool BinarySearchTree<T>::Search(T x)
    {
    	if(this->FindNode(x,_root)==NULL)
    	{
    		return false;
    	}
    	else return true;
    }
    
    

    插入一个新的结点

    template <class T>
    inline bool BinarySearchTree<T>::insert(BinaryTreeNode<T>* &root, T val)
    {
    	if (root == NULL)
    	{
    		root=new BinaryTreeNode<T>(val);
    		return true;
    	}
    	else if(val<root->_data){
    		insert(root->_left,val);
    	}
    	else if(val>root->_data){
    			insert(root->_right,val);
    		}
    	return false;
    }
    

    删除指定结点

    template <class T>
    inline BinaryTreeNode<T> * BinarySearchTree<T>::Remove(BinaryTreeNode<T> * &root,T val)
    {
    	if (root == NULL)
    			return NULL;
    
    		if (root->_data > val)
    			root->_left = Remove(root->_left, val);
    		else if (root->_data < val)
    			root->_right = Remove(root->_right, val);
    		else
    		{
    			if (root->_left == NULL&&root->_right == NULL)
    				root = NULL;
    			else if (root->_left == NULL)
    				root = root->_right;
    			else if (root->_right == NULL)
    				root = root->_left;
    			else
    			{
    				BinaryTreeNode<T> *minnode = root->_right;
    				while (minnode->_left != NULL)
    					minnode = minnode->_left;
    				root->_data = minnode->_data;
    				root->_right = Remove(root->_right, minnode->_data);
    			}
    		}
    		return root;
    }
    template <class T>
    inline bool BinarySearchTree<T>::Delete(T val)
    {
    	if (!Search(val))
    		return false;
    
    	Remove(_root, val);
    	return true;
    }
    
    

    是否为平衡树

    template <class T>
    inline bool BinarySearchTree<T>::isBalanced(BinaryTreeNode<T> * &root)
    {
    	if (!root)
    		return true;
    	if (!root->_left && !root->_right)
    		return true;
    	else if (abs(Size(root->_left) - Size(root->_right)) > 1)
    			return false;
    	else
    			return isBalanced(root->_left) && isBalanced(root->_right);
    }
    
    
    
    每一次写博客都是学习过程的记录,有什么问题大家提出来!我们一起讨论,欢迎留言!

    项目源代码传送门

  • 相关阅读:
    [转]在 javascript 按键事件中,按键值的对照表
    表达式树(Expression Tree)
    WPF之路——用户控件对比自定义控件UserControl VS CustomControl)
    wpf创建用户控件(计时器控件)
    WPF 命令
    WPF自定义DataGrid分页控件
    WPF ----在UserControl的xaml里绑定依赖属性
    wpf 自定义ListBox
    WPF 自定义NotifyPropertyChanged
    WPF 使用附加属性增加控件属性
  • 原文地址:https://www.cnblogs.com/xiangjunhong/p/12482471.html
Copyright © 2011-2022 走看看