数据结构之二叉搜索树的简单实现(C++实现)

功能

插入:insert()
查找:search()
删除:remove()
清除整个树:clear()
最大值:max()
最小值:min()
前序遍历:PreOrder()
中序遍历:InOrder()
后序遍历:PostOrder()
注:此二叉树允许插入相同的值,且默认将其放在右子树,因此以后会考虑写unique()函数

模板类的声明

template<typename T>
struct BSnode      //二叉树的结点
{
	T         data;   //数据
	BSnode<T> *lChild;//左孩子
	BSnode<T> *rChild;//右孩子
	BSnode<T> *parent;//双亲,方便删除操作
	BSnode(const T& Data, BSnode<T> *left, BSnode<T> *right, BSnode<T> *par):
		data(Data),lChild(left),rChild(right),parent(par){}
};


template<typename T>
class BStree {
	BSnode<T>  *root;
public:
	/*构造与析构函数*/
	BStree() :root(nullptr) {}
	BStree(int rootValue) { root = nullptr; insert(rootValue); }
	//BStree(const BStree<T>& that);
	~BStree();

	/*其他操作*/
	void insert(const T& data);                //插入一个数据
	BSnode<T>* search(const T& data) const;    //查找第一个相等的值的地址
	void remove(const T& data);		         //根据值删除结点
	void clear();                              //清除整个树
	BSnode<T>* max();						//找到最大值
	BSnode<T>* min();						//找到最小值

	/*遍历*/
	void PreOrder() const;
	void InOrder() const;
	void PostOrder() const;
	
private:
	void insert(BSnode<T>* pFindNode, BSnode<T>* pInsertNode);
	BSnode<T>* search(BSnode<T>* proot, const T& data) const;     //搜索
	void remove(BSnode<T>* pFind, BSnode<T>* pParent);		      //pFind为待删除的结点,pParent其双亲结点
	void clear(BSnode<T>*& proot);							  //注意,这里的参数一定要传引用或者二级指针。
	BSnode<T>* max(BSnode<T>* proot);							  //设置从proot开始找					 
	BSnode<T>* min(BSnode<T>* proot);							  //设置从proot开始找	  

	void PreOrder(BSnode<T> *proot) const;
	void InOrder(BSnode<T> *proot) const;
	void PostOrder(BSnode<T> *proot) const;

};

具体实现

template<typename T>
inline BStree<T>::~BStree()
{
	clear();
}

template<typename T>
inline void BStree<T>::insert(const T & data)
{
	BSnode<T> *pNode = new BSnode<T>(data, nullptr, nullptr,nullptr);
	if (root == nullptr)
		root = pNode;
	else
	{
		insert(root, pNode);
	}
}

template<typename T>
inline BSnode<T>* BStree<T>::search(const T & data) const
{
	return search(root,data);
}

template<typename T>
inline void BStree<T>::remove(const T & data)
{
	BSnode<T>* findNode = const_cast<BSnode<T>*>(search(data));
	if (findNode == nullptr)
		return;
	else
	{
		BSnode<T>* pTemp = findNode->rChild;
		remove(findNode, findNode->parent);
		while (pTemp != nullptr && pTemp->data == data)//如果仍然有相同的值,继续删除
		{
			remove(pTemp,pTemp->parent);
		}
	}
}

template<typename T>
inline void BStree<T>::PreOrder() const
{
	PreOrder(root);
}

template<typename T>
inline void BStree<T>::InOrder() const
{
	InOrder(root);
}

template<typename T>
inline void BStree<T>::PostOrder() const
{
	PostOrder(root);
}

template<typename T>
inline void BStree<T>::clear()
{
	clear(root);
}

template<typename T>
inline BSnode<T>* BStree<T>::max()
{
	return max(root);
}

template<typename T>
inline BSnode<T>* BStree<T>::min()
{
	return min(root);
}

template<typename T>
inline void BStree<T>::insert(BSnode<T>* pFindNode, BSnode<T>* pInsertNode)
{
	if (pFindNode->data > pInsertNode->data)
	{
		if (pFindNode->lChild == nullptr)
		{
			pFindNode->lChild = pInsertNode;
			pInsertNode->parent = pFindNode;
		}
		else
			insert(pFindNode->lChild, pInsertNode);
	}
	else
	{
		if (pFindNode->rChild == nullptr)
		{
			pFindNode->rChild = pInsertNode;
			pInsertNode->parent = pFindNode;
		}
		else
			insert(pFindNode->rChild, pInsertNode);
	}
}

template<typename T>
inline BSnode<T>* BStree<T>::search(BSnode<T>* proot, const T & data) const
{
	if (proot == nullptr)
		return nullptr;           //没找到返回空
	if (proot->data == data)
		return proot;
	else if (proot->data > data)
		return search(proot->lChild, data);
	else
		return search(proot->rChild, data);
}

template<typename T>
inline void BStree<T>::remove(BSnode<T>* pFind, BSnode<T>* pParent)
{
	if (pParent == nullptr) //不能删除根节点
		return;
	if (pFind->data < pParent->data)//如果要删除的值在左半部分
	{
		if (pFind->lChild == nullptr && pFind->rChild == nullptr) //如果是叶子结点
			pParent->lChild = nullptr;
		else if (pFind->rChild == nullptr)//如果右子树为空
		{
			pParent->lChild = pFind->lChild;
			pFind->lChild->parent = pParent;
		}
		else if (pFind->lChild == nullptr)//如果左子树为空
		{
			pParent->lChild = pFind->rChild;
			pFind->rChild->parent = pParent;
		}
		else//如果都不为空
		{
			BSnode<T>* par = pFind;
			BSnode<T>* s = pFind->rChild;
			while (s->lChild != nullptr)
			{
				par = s;
				s = s->lChild;
			}
			pFind->data = s->data;
			if (par == pFind)   //如果pFind的右孩子就是大于pFind值的最小值结点
				par->rChild = s->rChild;
			else
				par->lChild = s->rChild;

			if(s->rChild)
			s->rChild->parent = par;
			delete s;
			return;
		}
	}
	else               //如果要删除的值在右半部分
	{
		if (pFind->lChild == nullptr && pFind->rChild == nullptr) //如果是叶子结点
			pParent->rChild = nullptr;
		else if (pFind->rChild == nullptr)//如果右子树为空
		{
			pParent->rChild = pFind->lChild;
			pFind->lChild->parent = pParent;
		}
		else if (pFind->lChild == nullptr)//如果左子树为空
		{
			pParent->rChild = pFind->rChild;
			pFind->rChild->parent = pParent;
		}
		else//如果都不为空
		{
			BSnode<T>* par = pFind;
			BSnode<T>* s = pFind->lChild;
			while (s->rChild != nullptr)
			{
				par = s;
				s = s->rChild;
			}
			pFind->data = s->data;
			if (par == pFind)   //如果pFind的右孩子就是小于pFind值的最大值结点
				par->lChild = s->lChild;
			else
				par->rChild = s->lChild;

			if(s->lChild)
				s->lChild->parent = par;
			delete s;
			return;
		}
	}
	delete pFind;
}

template<typename T>
inline void BStree<T>::PreOrder(BSnode<T>* proot) const
{
	if (proot != nullptr)
	{
		cout << proot->data<<" ";
		PreOrder(proot->lChild);
		PreOrder(proot->rChild);
	}
}

template<typename T>
inline void BStree<T>::InOrder(BSnode<T>* proot)const
{
	if (proot != nullptr)
	{
		InOrder(proot->lChild);
		cout << proot->data << " ";
		InOrder(proot->rChild);
	}
}

template<typename T>
inline void BStree<T>::PostOrder(BSnode<T>* proot)const
{
	if (proot != nullptr)
	{
		PostOrder(proot->lChild);
		PostOrder(proot->rChild);
		cout << proot->data << " ";
	}
}

template<typename T>
inline void BStree<T>::clear(BSnode<T>*& proot)
{
	if (proot != nullptr)
	{
		clear(proot->lChild);     //递归删除左子树
		clear(proot->rChild);	  //递归删除右子树
		delete proot;
		proot = nullptr;
	}
}

template<typename T>
inline BSnode<T>* BStree<T>::max(BSnode<T>* proot)
{
	while (proot->rChild != nullptr)
		proot = proot->rChild;
	return proot;
}

template<typename T>
inline BSnode<T>* BStree<T>::min(BSnode<T>* proot)
{
	while (proot->lChild != nullptr)
		proot = proot->lChild;
	return proot;
}

测试代码

 #include<iostream>
#include"BStree.h"
using namespace std;

int main()
{
	using BSI = BStree<int>;
	BSI test(0);
	int arr[] = {0,-3,-6,-6,-6,-2,-2,1,9,2,9 };
	int n = sizeof(arr) / sizeof(int);
	for (int i = 0; i < n; ++i)
	{
		test.insert(arr[i]);
	}
	cout << "删除前:";
	test.PreOrder(); cout << endl; 
	BSnode<int>* find = test.search(1);
	test.remove(find->data);
	cout << "删除1 :"; test.PreOrder(); cout << endl;
	test.remove(-3); 
	cout << "删除-3:"; test.PreOrder(); cout << endl;
	test.remove(-6);
	cout << "删除-6:"; test.PreOrder(); cout << endl;
	test.remove(9);
	cout << "删除9 :"; test.PreOrder(); cout << endl;
	test.remove(-2);
	cout << "删除-2:"; test.PreOrder(); cout << endl;
	test.remove(0);
	cout << "删除0 :"; test.PreOrder(); cout << endl;
}

测试结果

1

猜你喜欢

转载自blog.csdn.net/qq_41041406/article/details/85074856