【数据结构】二叉搜索树的递归与非递归实现

一.什么是二叉搜索树

1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。

2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。 

3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。

4. 左右子树都是二叉搜索树。


二.二叉搜索树的代码实现(这里我们主要关心增删查改)

#pragma once
using namespace std;
template<class K>
struct SelectBinaryTreeNode
{
	typedef SelectBinaryTreeNode<K> Node;
	K _key;
	Node* _left;
	Node* _right;
	SelectBinaryTreeNode(const K& key)
		:_key(key)
		, _left(NULL)
		, _right(NULL)
	{}
};

template<class K>
class SelectBinaryTree
{
public:
	typedef SelectBinaryTreeNode<K> Node;
	SelectBinaryTree()
	{}
	SelectBinaryTree(const SelectBinaryTree& sbt)   //拷贝构造,递归实现
	{
		_root=_Copy(sbt._root);
	}
	~SelectBinaryTree()   //析构,递归实现
	{
		_Delete(_root);
	}

	bool Find(const K& key)    //非递归查找
	{
		if (NULL == _root)
			return false;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key)
				cur = cur->_right;
			else if (cur->_key>key)
				cur = cur->_left;
			else
				return true;
		}
		return false;
	}

	bool FindR(const K& key)    //递归查找
	{
		return _FindR(_root, key);
	}

	void InOrder()    //中序遍历
	{
		_InOrder(_root);
		cout << endl;
	}

	bool Insert(const K& key)    //非递归插入
	{
		if (NULL == _root)
		{
			_root = new Node(key);
			return true;
		}
		Node* cur = _root;
		Node* parent = NULL;
		while (cur)
		{
			if (cur->_key < key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key>key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
				return false;
		}
		if (parent->_key < key)
		{
			parent->_right = new Node(key);
		}
		else
			parent->_left = new Node(key);
		return true;
	}

	bool InsertR(const K& key)    //递归插入
	{
		return _InsertR(_root, key);
	}

	bool RemoveR(const K& key)   //递归删除
	{
		return _RemoveR(_root, key);
	}

	bool Remove(const K& key)    //非递归删除
	{
		if (NULL == _root)
			return false;
		Node* cur = _root;
		Node* parent = NULL;
		while (cur)
		{
			if (cur->_key < key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key>key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else   //找到了进行删除
			{
				Node* del = cur;

				if (cur->_left == NULL )  //左为空
				{
					if (parent == NULL) //要删除的是根节点
						_root = cur->_right;
					else
					{
						if (parent->_left == cur)
							parent->_left = cur->_right;
						else
							parent->_right = cur->_right;
					}
				}
				else if (cur->_right == NULL)  //右为空
				{
					if (NULL == parent)
						_root = cur->_left;
					else
					{
						if (parent->_left == cur)
							parent->_left = cur->_left;
						else
							parent->_right = cur->_left;
					}
				}

				else   //左右都不为空
				{
					Node* pcur = cur->_right;
					Node* pparent = cur;
					while (pcur->_left) //找到右树的最左结点
					{

						pparent = pcur;
						pcur = pcur->_left;
				
					}
					//K tmp = cur->_key;
					//cur->_key = pcur->_key;
					//pcur->_key = tmp;
					//找到后本应该像上面一样交换,但是因为pcur马上要删除,所以直接赋值就好
					cur->_key = pcur->_key;
					del = pcur;
					
					if (pparent->_left == pcur)
						pparent->_left = pcur->_right;
					else
						pparent->_right = pcur->_right;
					
					
				}
				delete del;
				return true;
			}	
		}
		return false;
	}
protected:

	bool _RemoveR(Node*& root, const K& key)
	{
		if (root->_key < key)
			return _RemoveR(root->_right, key);
		else if (root->_key>key)
			return _RemoveR(root->_left, key);
		else
		{
			Node* del = root;
			if (root->_left == NULL)  //要删除的结点左为空
			{
				root = root->_right;   
			}
			else if (root->_right == NULL )//要删除的结点右为空
			{
				root = root->_left;
			}

			else    //左右都不为空
			{
				Node* pcur = root->_right;
				while (pcur->_left)
				{
					pcur = pcur->_left;
				}
				root->_key = pcur->_key;
				del = pcur;
				
			}
			delete del;
			return true;
		}
		return false;
	}

	bool _InsertR(Node*& root, const K& key)
	{
		if (NULL == root)
		{
			root = new Node(key);
			return true;
		}
		if (root->_key < key)
			return _InsertR(root->_right, key);
		else if (root->_key>key)
			return _InsertR(root->_left, key);
		else
			return false;
	}

	bool _FindR(Node* root, const K& key)
	{
		if (NULL == root)
			return false;
		if (root->_key == key)
			return true;
		else if (root->_key < key)
			_FindR(root->_right, key);
		else if (root->_key>key)
			_FindR(root->_left, key);

	}
	void _Delete(Node* root)   //递归删除
	{
		if (root)
		{
			_Delete(root->_left);
			_Delete(root->_right);
			delete root;
		}
	}
	Node* _Copy(Node* sroot)   //递归拷贝
	{
		Node* cur = NULL;
		if (sroot)
		{
			cur = new Node(sroot->_key);
			cur->_left = _Copy(sroot->_left);
			cur->_right = _Copy(sroot->_right);
		}
		return cur;
	}
	void _InOrder(Node* root)
	{
		if (NULL == root)
			return;
		_InOrder(root->_left);
		cout << root->_key<<" ";
		_InOrder(root->_right);
	}
private:
	Node* _root;
};

void TestSelectBinaryTree()  //测试非递归版
{
	int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	SelectBinaryTree<int> sbt;
	for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		sbt.Insert(a[i]);
	}
	SelectBinaryTree<int> sbt1(sbt);  //测试拷贝构造
	sbt1.InOrder();
	sbt.InOrder();
	sbt.Remove(0);
	sbt.Remove(1);
	sbt.Remove(2);
	sbt.Remove(3);
	sbt.Remove(4);
	sbt.Remove(5);
	sbt.Remove(6);
	sbt.Remove(7);
	sbt.Remove(8);
	sbt.Remove(9);
	sbt.InOrder();
	//cout<<sbt.Find(11)<<endl;

}

void TestSelectBinaryTreeR()  //测试递归版
{
	int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	SelectBinaryTree<int> sbt;
	for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		sbt.InsertR(a[i]);
	}
	SelectBinaryTree<int> sbt1(sbt);  //测试拷贝构造
	sbt1.InOrder();
	sbt.InOrder();
	sbt.RemoveR(0);
	sbt.InOrder();
	sbt.RemoveR(1);
	sbt.InOrder();
	sbt.RemoveR(2);
	sbt.InOrder();
	sbt.RemoveR(3);
	sbt.InOrder();
	sbt.RemoveR(4);
	sbt.InOrder();
	sbt.RemoveR(5);
	sbt.InOrder();
	sbt.RemoveR(6);
	sbt.InOrder();
	sbt.RemoveR(7);
	sbt.InOrder();
	sbt.RemoveR(8);
	sbt.InOrder();
	sbt.RemoveR(9);
	sbt.InOrder();

	//cout<<sbt.FindR(11)<<endl;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值