C++——二叉搜索树

73 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

二叉搜索树

 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

二叉搜索树实现 非递归插入|非递归查找

#include<iostream>
using namespace std;
template<class K>
class BStreeNode
{
public:
	BStreeNode(const K& key)
		:_left(nullptr),
		_right(nullptr),
		_key(key)
	{}
	BStreeNode<K>* _left;
	BStreeNode<K>* _right;
	K _key;
};
template<class K>
class BStree
{
	typedef BStreeNode<K> Node;
public:
	bool Insert(const K& key)
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}
 
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key > key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}
 
		cur = new Node(key);
		if (parent->_key < key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
 
		return true;
	}
bool Find(const K& key)//查找
	{
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key)
			{
				cur = cur->_right;
			}
			else if (cur->_key > key)
			{
				cur = cur->_left;
			}
			else
			{
				return true;
			}
		}
 
		return true;
	}
	void InOrder()
	{
		_InOrder(_root);
	}
private:
	void _InOrder(Node *root)
	{
		if (root == nullptr)
			return;
		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}
private:
	Node* _root = nullptr;
};
int main()
{
	BStree<int> t;
	int a[] = { 1,1,2,2,3,6,165,132,4185,123 };
	for (auto e : a)
	{
		t.Insert(e);
	}
	t.InOrder();
	return 0;
}

非递归删除代码

bool Erase(const K& key)//删除
{
        //若有一个子节点,删除父节点后,让子节点填充
        //若有俩个子节点,父节点删除后
        //1.用左子树的最大节点替换父节点
        //2.或右子树的最小节点替换父节点
        Node* parent = nullptr;
        Node* cur = _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->_left == nullptr)//如果要删除的节点左为空
                        {
                                if (cur == _root)//如果要删除的是根节点(这种情况根节点只有右子树,因为左为空)
                                {
                                        _root = cur->_right;
                                }
                                else
                                {
                                        if (cur == parent->_left)//判断要删除的节点是父亲的左节点还是右节点
                                        {
                                                parent->_left = cur->_right;
                                        }
                                        else
                                        {
                                                parent->_right = cur->_right;
                                        }
                                }
                                delete cur;
                                cur = nullptr;
                        }
                        else if (cur->_right == nullptr)//如果要删除的节点右为空
                        {
                                if (cur == _root)
                                {
                                        _root = cur->_left;
                                }
                                else
                                {
                                        if (cur == parent->_left)//判断要删除的节点是父亲的左节点还是右节点
                                        {
                                                parent->_left = cur->_left;
                                        }
                                        else
                                        {
                                                parent->_right = cur->_left;
                                        }
                                }
                                delete cur;
                                cur = nullptr;
                        }
                        else//左右都为空,叶子节点,这里采用用右树的最小节点进行删除
                        {
                                Node* minParent = cur;
                                Node*min = cur->_right;//cur是要删除的节点
                                while (min->_left)//寻找最小节点
                                {
                                        minParent = min;
                                        min = min->_left;
                                }
                                swap(cur->_key, min->_key);
                                if (minParent->_left == min)
                                {
                                        minParent->_left = min->_right;
                                }
                                else
                                minParent->_right = min->_right;
                                delete min;
                        }
                        return true;
                }
        }
        return false;
}