【C++】实现一个二叉搜索树

 


目录

二叉搜索树的概念

1.结点定义

2.构造、析构、拷贝构造、赋值重载

3.插入、删除、查找、排序

3.1插入

3.2插入递归版

3.3查找指定值

3.3查找指定值递归版

3.4中序遍历

3.5删除

最后


二叉搜索树的概念

二叉搜索树又称为二叉排序树或二叉查找树,它或者是一棵空树,或者是具有以下性质的二叉树:

  • 非空左子树上所有结点的值都小于根结点的值。
  • 非空右子树上所有结点的值都大于根结点的值。
  • 左右子树都是二叉搜索树。

1.结点定义

template
struct BSTreeNode
{
	BSTreeNode* _left;
	BSTreeNode* _right;
	K _key;

	BSTreeNode(const K& key)
		:_key(key)
		,_left(nullptr)
		,_right(nullptr)
	{}
};

2.构造、析构、拷贝构造、赋值重载

    //构造函数
	BSTree()
		: _root(nullptr)
	{

	}

	//析构函数
	~BSTree()
	{
		//递归删除
		Destroy(_root);
		_root = nullptr;
	}

	
	//拷贝构造
	BSTree(const BSTree& t)
	{
	     //递归去拷贝
		_root = Copy(t._root);
		
	}

	//赋值重载
	BSTree& operator=(BSTree t)//注意这里传参,传值传参,默认已经拷贝构造新的一份了
	{
		swap(_root, t._root);//这里直接交换return 就好
		return *this;
	}
	  

	Node* Copy(Node* root)
	{
		//前序遍历
		if (root == nullptr)
		{
			return nullptr;
		}

		Node* newRoot = new Node(root->_key);
		//建立联系,不是简单的调用
		newRoot->_left = Copy(root->_left);
		newRoot->_right = Copy(root->_right);
		return newRoot;
	}
   
    void Destroy(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		Destroy(_root->_left);
		Destroy(_root->_right);
		delete(root);
	}

3.插入、删除、查找、排序

3.1插入

bool Insert(const K& key)
	{
		//不允许相等数据插入版本,减少冗余
		//空树
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}
 
		//正常插入
		Node* cur = _root;
		Node* parent = _root;
		while (cur != nullptr)
		{
			if (key > cur->_key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (key < cur->_key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}
		cur = new Node(key);
		if (key > parent->_key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		return true;

	}

3.2插入递归版

bool InsertR(const K& key)//注意参数
	{
		return _InsertR(_root, key);
	}
bool _InsertR(Node* &root,const K& key)
	{
		if (root == nullptr)
		{
			root = new Node(key);
			return true;
		}
		if (root->_key > key)
		{
			return _InsertR(root->_left, key);
		}
		else if (root->_key < key)
		{
			return _InsertR(root->_right, key);

		}
		else
		{
			//相等
			return false;
		}
		
	}

3.3查找指定值

bool Find(const K& key)
	{
		Node* cur = _root;
		while (cur!=nullptr)
		{
			if (cur->_key > key)
			{
				cur = cur->_left;
			}
			else if (cur->_key < key)
			{
				cur = cur->_right;
			}
			else
			{
				return true;
			}
		}
		return false;
	}

3.3查找指定值递归版

    bool FindR(const K& key)
	{
		return _FindR(_root, key);
	}
    
    bool _FindR(Node*& root, const K& key)
	{
		if (root == nullptr)
		{
			return false;
		}

		if (root->_key == key)
		{
			return true;
		}

		if (root->_key > key)
		{
			return _FindR(root->_left, key);
		}
		else 
		{
			return _FindR(root->_right, key);

		}
		
		
	}

3.4中序遍历

    void InOrder()
	{
		_InOrder(_root);
	}
    void _InOrder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}

3.5删除

bool Erase(const K& key)
	{
		Node* cur = _root;
		Node* parent = _root;
		while (cur)
		{
			//找到节点
			if (cur->_key > key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (cur->_key < key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				//找到了
				//删除没有孩子或者只有一种孩子的节点

				//这个是普通节点
				if (cur->_right == nullptr)
				{
					if (parent->_left == cur)
					{
						parent->_left = cur->_left;
					}
					if (parent->_right == cur)
					{
						parent->_right = cur->_left;
					}
				    if(parent==cur)//是根结点
					{
						parent = parent->_left;
					}
					delete(cur);
					return true;
					
				}
				else if(cur->_left==nullptr)
				{
					if (parent->_left == cur)
					{
						parent->_left = cur->_right;
					}
					if (parent->_right == cur)
					{
						parent->_right = cur->_right;
					}
					if (parent == cur)//是根结点
					{
						parent = parent->_right;
					}
					delete(cur);
					return true;

				}
				else
				{
					//左右都不为空
				    //替换法删除,找右子树的最小值
					Node* miniright = cur->_right;
					Node* minirightp = cur;

					while (miniright->_left != nullptr)
					{
						minirightp = miniright;
						miniright = miniright->_left;
					}
					cur->_key = miniright->_key;
					if (minirightp->_left == miniright)
					{
						minirightp->_left = miniright->_right;
					}
					if (minirightp->_right == miniright)
					{
						minirightp->_right = miniright->_right;
					}
					delete(miniright);
					return true;

				}
				

			}
		}
		return false;

	}


最后

加油

【C++】实现一个二叉搜索树_第1张图片

你可能感兴趣的:(C++修炼之旅,c++,二叉搜索树,搜索二叉树)