二叉搜索树和红黑树概述以及模板实现(1)

39 篇文章 0 订阅

最近研究了一下算法导论里面关于二叉搜索树和红黑树的一章,对于红黑树的内容虽然还没有完全消化吸收,写一篇blog算是对所有内容的一个复习和反思吧。

1. 二叉搜索树

二叉搜索树是一颗二叉树,要求对于任何一个节点,它的左儿子内的数据要小于根节点数据,而右节点的数据要大于根节点内的数据。

例如


在搜索问题中,虽然哈希表在比较好的情况下可以提供O(1)的时间,但是对于数据分布不好,或者数据较少的时候会造成聚集或者空间浪费。但是用搜索树,在检索效率平均是lnN

下面用看《算法导论》实现的算法分析一些具体的操作,其实基本的操作和一般的二叉树一样,包括插入、删除、遍历等。只不过因为树结构的特殊,在操作后要做一些处理。


#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H

#include <assert.h>

#include <stack>
#include <iostream>


namespace DataStructure
{
        //模板节点
	template <typename T>
	class TreeNode
	{
	public:
		T data;
		TreeNode *left,*right;
		TreeNode *parent;
		
		TreeNode()
		{
			parent = left = right = NULL;
		}
		TreeNode(T _data)
		{
			data = _data;
			parent = left = right = NULL;
		}
	};

	template<typename T>
	class BinarySearchTree
	{
	public:
		typedef TreeNode<T> NodeType;
	public:
		BinarySearchTree()
		{
			m_pRoot = NULL;
		}

		/*
		* Add a element into tree
		*/
		TreeNode<T>* insert(T _element);

		/*
		* Find a element
		*/
		TreeNode<T>* search(T _element) const;

		/*
		* delete an element
		*/
		bool delete_element(TreeNode<T> *_pElement);

		/**search the element interactively*/
		TreeNode<T>* interative_search(T data);

		/**the minimum element of the tree*/
		TreeNode<T>* minimum_element(TreeNode<T> *)const;

		/**the maximum element*/
		TreeNode<T>* maximum_element(TreeNode<T> *)const;

		/**tree successor */
		TreeNode<T>* successor(TreeNode<T>* pElement) const;

		/**tree predecessor */
		TreeNode<T>* predecessor(TreeNode<T> *pElement)const;

		/**iterate all elements*/
		void print_ordered_elements()const;

		/**
		* delete one node from the tree
		*/
	

	private:
		TreeNode<T> * m_pRoot;
	};

	/*
	* Add a element into tree
	*/
	template<typename T>
	TreeNode<T>* BinarySearchTree<T>::insert(T _element)
	{
		if(m_pRoot == NULL)
		{
			m_pRoot = new TreeNode<T>;
			m_pRoot->data = _element;
			m_pRoot->left = m_pRoot->right = NULL;
			return m_pRoot;
		}
		else
		{
			TreeNode<T> *pNode = m_pRoot;
			while(pNode != NULL)
			{
				if( _element > pNode->data )
				{
					//insert into right subtree
					//pNode = pNode->right;

					//make the current element be the right son.
					if(pNode->right == NULL)
					{
						TreeNode<T> *pNewElement = new TreeNode<T>;
						pNewElement->data = _element;
						pNewElement->left = NULL;
						pNewElement->right = NULL;
						pNewElement->parent = pNode;
						pNode->right = pNewElement;
						return pNewElement;
					}
					else
					{
						pNode = pNode->right;
					}
					
				}
				else if(_element < pNode->data )
				{
					//insert into left subtree
					//pNode = pNode->left;
					if(pNode->left == NULL)
					{
						TreeNode<T> *pNewElement = new TreeNode<T>;
						pNewElement->data = _element;
						pNewElement->left = NULL;
						pNewElement->right = NULL;
						pNewElement->parent = pNode;
						pNode->left = pNewElement;
						return pNewElement;
					}
					else
					{
						pNode = pNode->left;
					}
				}
				else
				{
					return pNode;
				}

			}
		}
		return NULL;
	}

	/*
	* Find an element
	* if there is no such element return NULL
	*/
	template<typename T>
	TreeNode<T>* BinarySearchTree<T>::search(T _element) const
	{
		TreeNode<T> *pElement = m_pRoot;
		while(pElement != NULL)
		{
			//search the left
			if(_element < pElement->data)
			{
				pElement = pElement->left;
			}
			else if(_element > pElement->data)
			{
				pElement = pElement->right;
			}
			else
			{
				return pElement;
			}
		}
		return NULL;
	}

	/*
	* delete an element
	*/
	template<typename T>
	bool BinarySearchTree<T>::delete_element(TreeNode<T> *_pElement)
	{
		//assert
		//assert(_pElement != NULL && m_pRoot != NULL);
		if(_pElement == NULL || m_pRoot == NULL)
		{
			return false;
		}
		TreeNode<T> *realDelete = NULL;
		TreeNode<T> *pSon = NULL;

		if(_pElement ->left == NULL || _pElement->right == NULL)
		{
			realDelete = _pElement;
		}
		else
		{
			realDelete = successor(_pElement);
		}

		if(realDelete->left != NULL)
		{
			pSon = realDelete->left;
		}
		else
		{
			pSon = realDelete->right;
		}

		if(pSon != NULL)
		{
			pSon->parent = realDelete->parent;
		}
	

		if(realDelete ->parent != NULL)
		{
			if(realDelete->parent->left == realDelete)
			{
				realDelete->parent->left = pSon;
			}
			else
			{
				realDelete->parent->right = pSon;
			}

			if(_pElement != realDelete)
			{
				_pElement->data = realDelete->data;
				delete realDelete;
			}
		}
		else
		{
			delete m_pRoot;
			m_pRoot = NULL;
		}
		return true;
		//this is what age
	}


	/**the minimum element of the tree*/
	template<typename T>
	TreeNode<T>* BinarySearchTree<T>::minimum_element(TreeNode<T> *pCNode)const
	{
		TreeNode<T> *pNode = pCNode;
		while(pNode->left != NULL)
		{
			pNode = pNode->left;
		}
		return pNode;
	}

	/**the maximum element*/
	template<typename T>
	TreeNode<T>* BinarySearchTree<T>::maximum_element(TreeNode<T> *pCNode)const
	{
		TreeNode<T> *pNode = pCNode;
		while(pNode->right != NULL)
		{
			pNode = pNode->right;
		}
		return pNode;
	}

	//print 
	template<typename T>
	void BinarySearchTree<T>::print_ordered_elements()const
	{
		std::stack<TreeNode<T>*> elements;
		TreeNode<T>* tmp = m_pRoot;
		elements.push(m_pRoot);
		std::cout<<"All Elements\n";
		while(!elements.empty())
		{
			while(tmp != NULL)
			{
				tmp = tmp ->left;
				elements.push(tmp);
			}
			
			elements.pop();

			if(!elements.empty())
			{
				tmp = elements.top();
				elements.pop();

				std::cout<<tmp->data<<std::endl;
				tmp = tmp->right;
				elements.push(tmp);
			}
		}
	}
	/**tree successor */
	template<typename T>
	TreeNode<T>* BinarySearchTree<T>::successor(TreeNode<T>* pElement) const
	{
		if(pElement->right != NULL)
		{
			return minimum_element(pElement->right);
		}
		
		TreeNode<T>* pNode = pElement->parent;
		while(pNode != NULL && pNode ->right == pElement)
		{
			pElement = pNode;
			pNode = pNode->parent;
		}
		return pNode;
		
	}

	/**tree predecessor */
	template<typename T>
	TreeNode<T>* BinarySearchTree<T>::predecessor(TreeNode<T> *pElement)const
	{
		if(pElement->left != NULL)
		{
			return maximum_element(pElement->left);
		}

		TreeNode<T>* pNode = pElement->parent;
		while(pNode != NULL && pNode ->left == pElement)
		{
			pElement = pNode;
			pNode = pNode->parent;
		}
		return pNode;
	}



	



}//namespace DataStructure

#endif //BINARY_SEARCH_TREE_H


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值