二叉搜搜索树-懒惰删除

#include <algorithm>
#include <iostream>
#include <stack>

template <typename Comparable>
class BSTree
{
private:
	struct BinaryNode
	{
		Comparable element;
		bool deleted;  //增加bool变量,记录元素是否删除。
		BinaryNode* left, * right;
		explicit BinaryNode(const Comparable& el = Comparable{}, bool de = false,
			BinaryNode* le = nullptr, BinaryNode* ri = nullptr) :
			element(el), deleted(false), left(le), right(ri) {};
	};
	BinaryNode* root;


public:
	BSTree()
	{
		root = nullptr;
	}
	BSTree(const BSTree& rhs)
	{
		root = clone(rhs.root);
	}
	BSTree(BSTree&& rhs) : root(rhs.root)
	{
		rhs.root = nullptr;
	}
	BSTree& operator = (const BSTree& rhs)
	{
		BSTree copy = rhs;
		std::swap(*this, copy);
		return *this;
	}
	BSTree& operator = (BSTree&& rhs)
	{
		std::swap(root, rhs.root);
		return *this;
	}
	~BSTree()
	{
		makeEmpty();
	}

	const Comparable& findMax() const
	{
		return findMax(root)->element;
	}
	const Comparable& findMin() const
	{
		return findMin(root)->element;
	}
	bool contains(const Comparable& x) const
	{
		return contains(x, root);
	}
	bool isEmpty() const
	{
		return root == nullptr;
	}
	void printTree(ostream& out = cout) const
	{
		printTree(root, out);
	}
	void makeEmpty()
	{
		makeEmpty(root);
	}
	void insert(const Comparable& x)
	{
		insert(x, root);
	}
	void remove(const Comparable& x)
	{
		remove(x, root);
	}

private:
	BinaryNode* findMax(BinaryNode* t) const
	{
		if (t == nullptr || t->deleted == true)
		{
			return nullptr;
		}
		while (t->right != nullptr && t->right->deleted != true)
		{
			t = t->right;
		}
		return t;

	}
	BinaryNode* findMin(BinaryNode* t) const
	{
		if (t == nullptr || t->deleted == true)
		{
			return nullptr;
		}
		while (t->left != nullptr && t->left->deleted != true)
		{
			t = t->left;
		}
		return t;
	}
	bool contains(const Comparable& x, BinaryNode* t) const
	{
		if (t == nullptr || t->deleted == true)
		{
			return false;
		}
		while (x < t->element && t->left != nullptr && t->left->deleted != true ||
			x > t->element && t->right != nullptr && t->right->deleted != true)
		{
			if (x < t->element && t->left != nullptr && t->left->deleted != true)
			{
				t = t->left;
			}
			else
			{
				t = t->right;
			}
		}
		return x == t->element;
	}
	void printTree(BinaryNode* t, ostream& out) const//中序遍历迭代版本
	{
		BinaryNode* p = t;
		stack<BinaryNode*> st;
		while (p != nullptr && p->deleted != true || !st.empty())
		{
			if (p != nullptr && p->deleted != true)
			{
				st.push(p);
				p = p->left;
			}
			else
			{
				p = st.top(); st.pop();
				out << p->element << endl;
				p = p->right;
			}
		}
	}
	void makeEmpty(BinaryNode*& t)//后续遍历删除结点
	{
		BinaryNode* p = t, * r = nullptr;
		stack<BinaryNode*> st;
		while (p != nullptr || !st.empty())
		{
			if (p != nullptr)
			{
				st.push(p);
				p = p->left;
			}
			else
			{
				p = st.top();
				if (p->right != nullptr && p->right != r)
				{
					p = p->right;
				}
				else
				{
					p = st.top(); st.pop();
					r = p;
					delete p;
					p = nullptr;
				}
			}
		}

	}
	void insert(const Comparable& x, BinaryNode*& t)
	{
		if (t == nullptr)
		{
			t = new BinaryNode(x);
		}
		else if (t->deleted == true)
		{
			t->element = x;
			t->deleted = false;
		}
		BinaryNode* p = t;
		while (x < p->element && p->left != nullptr && p->left->deleted != true ||
			x > p->element && p->right != nullptr && p->right->deleted != true)
		{
			if (x < p->element && p->left != nullptr && p->left->deleted != true)
			{
				p = p->left;
			}
			else
			{
				p = p->right;
			}
		}
		if (p->element != x)
		{
			if (x < p->element)
			{
				if (p->left != nullptr)
				{
					p->left->element = x;
					p->left->deleted = false;
				}
				else
				{
					p->left = new BinaryNode(x);
				}
			}
			if (x > p->element)
			{
				if (p->right != nullptr)
				{
					p->right->element = x;
					p->right->deleted = false;
				}
				else
				{
					p->right = new BinaryNode(x);
				}
			}
		}

	}
	void remove(const Comparable& x, BinaryNode*& t)
	{
		if (t == nullptr || t->deleted == true)
		{
			return;
		}
		BinaryNode* p = t;
		while (x < p->element && p->left != nullptr && p->left->deleted != true ||
			x > p->element && p->right != nullptr && p->right->deleted != true)
		{
			if (x < p->element && p->left != nullptr && p->left->deleted != true)
			{
				p = p->left;
			}
			else
			{
				p = p->right;
			}
		}
		if (x == p->element)
		{
			//删除结点左右子树不为空(保留的删除结点也算为空节点),则用其前驱或后继结点替代,转化删除结点为叶子结点(左右子树为空或删除结点)
			if (p->left != nullptr && p->left->deleted != true || p->right != nullptr && p->right->deleted != true)
			{
				if (p->left != nullptr && p->left->deleted != true)
				{
					p->element = findMin(p->left)->element;
					remove(p->element, p->left);
				}
				else
				{
					p->element = findMin(p->right)->element;
					remove(p->element, p->right);
				}
			}
			else
			{
				p->deleted = true;
			}

		}

	}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值