二叉搜索树【BST】c++实现


#include <iostream>
#include <memory>
#include <stack>
#include <initializer_list>

template <typename T>
class Node
{
public:
	Node(T *a) :p(NULL), left(NULL), right(NULL)
	{
		data.reset(a);
	}
	Node(Node &) = delete;
	Node &operator = (Node &) = delete;
	~Node() { }

	bool operator != (const T &a)
	{
		return (*data != a);
	}
	bool operator < (const T &a)
	{
		return (*data < a);
	}

	Node *p;
	Node *left;
	Node *right;
	
	std::shared_ptr<T> data;
};
//Binary Search Tree
template <typename T>
class BST
{
public:
	BST() :root(NULL) { }
	BST(std::initializer_list<T> l) :root(NULL)
	{
		auto beg = l.begin();

		while (beg != l.end())
		{
			auto a = new T(*beg);
			TreeInsert(a);
			++beg;
		}
	}
	~BST()
	{
		DeleteWholeTree();
	}
	Node<T> *Predecessor(Node<T> *)const;
	Node<T> *Successor(Node<T> *)const;
	bool TreeInsert(T *);
	bool TreeDelete(const T &);
	std::weak_ptr<T> TreeSearch(const T &)const;
	void InorderTreeWalk()const;
private:
	void DeleteWholeTree();

	Node<T> *root;
};

template <typename T> 
inline Node<T> *Maximum(Node<T> *a)
{
	while (a->right != NULL)
	{
		a = a->right;
	}
	return a;
}
template <typename T>
inline Node<T> *BST<T>::Predecessor(Node<T> *a)const
{
	if (a->left != NULL)
		return Maximum(a->left);
	
	auto temp = a->p;

	while (temp != NULL&&temp->right != a)
	{
		a = temp;
		temp = temp->p;
	}
	return temp;
}

template <typename T>
inline Node<T> *Minimum(Node<T> *a)
{
	while (a->left != NULL)
	{
		a = a->left;
	}
	return a;
}
template <typename T>
inline Node<T> *BST<T>::Successor(Node<T> *)const
{
	if (a->right != NULL)
		return Minimum(a->right);

	auto temp = a->p;

	while (temp != NULL&&temp->left != a)
	{
		a = temp;
		temp = temp->p;
	}
	return temp;
}

template <typename T>
inline bool BST<T>::TreeInsert(T *a)
{
	//Data must be unique
	if (auto temp = TreeSearch(*a).lock())
	{
		std::cout << "data " << *temp 
			<< " already exists" << std::endl;
		return false;
	}
	auto x = root;
	decltype(x) y = NULL;

	while (x != NULL)
	{
		y = x;

		if (*x < *a)
			x = x->right;
		else
			x = x->left;
	}
	//Build a new Node
	auto newNODE = new Node<T>(a);
	newNODE->p = y;

	if (y == NULL)
		root = newNODE;
	else if (*y < *a)
		y->right = newNODE;
	else
		y->left = newNODE;

	return true;
}

template <typename T>
inline std::weak_ptr<T>
BST<T>::TreeSearch(const T &k)const
{
	auto temp = root;

	while (temp != NULL&&*temp != k)
	{
		if (*temp < k)
			temp = temp->right;
		else
			temp = temp->left;
	}
	if (temp == NULL)
		return std::weak_ptr<T>();
	else
		return std::weak_ptr<T>(temp->data);
}
// Substitute Second for First
template <typename T>
inline void TransplantChildTree(T *&root, T *first, T *second)
{
	if (first->p == NULL)
		root = second;
	else
		(first->p->left == first) ?
		(first->p->left = second) :
		(first->p->right = second);

	if (second != NULL)
		second->p = first->p;
}
template <typename T>
inline bool BST<T>::TreeDelete(const T &k)
{
	auto a = root;

	while (a != NULL&&*a != k)
	{
		if (*a < k)
			a = a->right;
		else
			a = a->left;
	}
	if (a == NULL)
	{
		std::cout << "data " << *temp
			<< "  is non-existent" << std::endl;
		return false;
	}
	if (a->left == NULL)
		TransplantChildTree(root, a, a->right);
	else if (a->right == NULL)
		TransplantChildTree(root, a, a->left);
	else
	{
		auto temp = Minimum(a->right);

		if (temp != a->right)
		{
			TransplantChildTree(root, temp, temp->right);
			temp->right = a->right;
			a->right->p = temp;
		}

		TransplantChildTree(root, a, temp);
		temp->left = a->left;
		a->left->p = temp;
	}
	delete a;
	return true;
}
 //Inorder Traversal
template <typename T>
inline void BST<T>::InorderTreeWalk()const
{
	auto x = root;
	std::stack<decltype(x)> temp;

	while (x != NULL || !temp.empty())
	{
		while (x != NULL)
		{
			temp.push(x);
			x = x->left;
		}
		if (!temp.empty())
		{
			x = temp.top();
			std::cout << *x->data << " ";
			x = x->right;
			temp.pop();
		}
	}
	std::cout << std::endl;
}

template <typename T>
inline void BST<T>::DeleteWholeTree()
{
	auto x = root;
	std::stack<decltype(x)> temp;
	std::stack<decltype(x)> pointer;

	while (x != NULL || !temp.empty())
	{
		while (x != NULL)
		{
			temp.push(x);
			x = x->left;
		}
		if (!temp.empty())
		{
			x = temp.top();
			pointer.push(x);
			x = x->right;
			temp.pop();
		}
	}
	while (!pointer.empty())
	{
		delete pointer.top();
		pointer.pop();
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值