漫话算法:手把手教你手搓二叉搜索树(从今天起我也是员神了)

148 篇文章 1 订阅
129 篇文章 1 订阅

1.切记节点构建模板即可

template<class T>
struct BSTNode
{
BSTNode<T>left;
BSTNode<T>right;
T val;
}

2.整体调用

1.将主体封装为一个模板类,再使用typedef简化节点名称

struct BSTNode
{
	BSTNode<T> left;
	BSTNode<T>right;
	T val;
};
template<class T>
class bstree
{
	typedef BSTNode node;
	node* root = nullptr;
};

3.构造函数迭代

1.整体思路:插入后的节点必为叶子节点,所以要一直往下比较,如果出现相同值,说明无需插入操作,返回false,pcur用来记录cur变换前的位置,如果cur已将二叉搜索树遍历完,则让它根据值的比较成为pcur的一个节点

struct BSTNode
{
	BSTNode<T> left;
	BSTNode<T>right;
	T val;
};
template<class T>
class bstree
{
	typedef BSTNode node;
	node* root = nullptr;
public:
	bool insert(const T&key)
	{
		if (root == nullptr)
		{
			root = new node(key);
			return true;
		}
		else
		{
			node* cur = root;
			node* pcur = nullptr;
			while (cur)
			{
				if (key > cur->val)
				{
					pcur = cur;
					cur = cur->right;
				}
				else if (key < cur->val)
				{
					pcur = cur;
					cur = cur->left;
				}
				else
				{
					return false;
				}
			}
			cur = new node(key);
			if (pcur->val < key)
			{
				cur = pcur->right;
				return true;
			}
			else
			{
				cur = pcur->left;
				return true;
			}
		}
	}
};

4.前序遍历函数(这个是二叉树基础,就不再赘述)

struct BSTNode
{
	BSTNode<T> left;
	BSTNode<T>right;
	T val;
};
template<class T>
class bstree
{
	typedef BSTNode node;
	node* root = nullptr;
public:
	bool insert(const T&key)
	{
		if (root == nullptr)
		{
			root = new node(key);
			return true;
		}
		else
		{
			node* cur = root;
			node* pcur = nullptr;
			while (cur)
			{
				if (key > cur->val)
				{
					pcur = cur;
					cur = cur->right;
				}
				else if (key < cur->val)
				{
					pcur = cur;
					cur = cur->left;
				}
				else
				{
					return false;
				}
			}
			cur = new node(key);
			if (pcur->val < key)
			{
				cur = pcur->right;
				return true;
			}
			else
			{
				cur = pcur->left;
				return true;
			}
		}
	}
	void fprint(node* point = root)
	{
		if (root == nullptr)
		{
			return;
		}
		cout << root->val;
		fprint(root->left);
		fprint(root->right);
	}
};

5.查找函数(也很简单)

struct BSTNode
{
	BSTNode<T> left;
	BSTNode<T>right;
	T val;
};
template<class T>
class bstree
{
	typedef BSTNode node;
	node* root = nullptr;
public:
	bool insert(const T&key)
	{
		if (root == nullptr)
		{
			root = new node(key);
			return true;
		}
		else
		{
			node* cur = root;
			node* pcur = nullptr;
			while (cur)
			{
				if (key > cur->val)
				{
					pcur = cur;
					cur = cur->right;
				}
				else if (key < cur->val)
				{
					pcur = cur;
					cur = cur->left;
				}
				else
				{
					return false;
				}
			}
			cur = new node(key);
			if (pcur->val < key)
			{
				cur = pcur->right;
				return true;
			}
			else
			{
				cur = pcur->left;
				return true;
			}
		}
	}
	void fprint(node* point = root)
	{
		if (root == nullptr)
		{
			return;
		}
		cout << root->val;
		fprint(root->left);
		fprint(root->right);
	}
	bool find(const T& data)
	{
		if (root == nullptr)
		{
			return false;
		}
		node* cur = root;
		while (cur)
		{
			if (cur->val == data)
			{
				return true;
			}
			else if (cur->val > data)
			{
				cur = cur->left;
			}
			else
			{
				cur = cur->eight;
			}
		}
		return false;
	}
};

6.删除函数

1.首先定义pcur记录cur的位置,然后找到需要删除的节点,此时要观察删除节点的情况,分为左边有树,右边有树,都有树,三种情况首先要处理根节点的情况,前两者直接把它残留的左右节点赋给根节点,后者之后讲。接下来,前两者要判断cur是pcur的左节点还是右节点,然后执行操作留左接左,留右接右,就是将cur所占的位置(左节点或右节点)接cur留存的树,第三种情况也是最复杂的,取右树最小节点代替被删除节点,还是定义pminr与minr,直到找到右树的最小节点,然后与目标节点交换值,此时问题又来了,minr是pminr的左节点还是右节点?,口诀来了,右左右左,左右右右,就是当minr是pminr左节点时,如果minr存在右节点,则pminr的左节点=minr的右节点,pminr的左节点为空

struct BSTNode
{
	BSTNode<T> left;
	BSTNode<T>right;
	T val;
};
template<class T>
class bstree
{
	typedef BSTNode node;
	node* root = nullptr;
public:
	bool insert(const T&key)
	{
		if (root == nullptr)
		{
			root = new node(key);
			return true;
		}
		else
		{
			node* cur = root;
			node* pcur = nullptr;
			while (cur)
			{
				if (key > cur->val)
				{
					pcur = cur;
					cur = cur->right;
				}
				else if (key < cur->val)
				{
					pcur = cur;
					cur = cur->left;
				}
				else
				{
					return false;
				}
			}
			cur = new node(key);
			if (pcur->val < key)
			{
				cur = pcur->right;
				return true;
			}
			else
			{
				cur = pcur->left;
				return true;
			}
		}
	}
	void fprint(node* point = root)
	{
		if (root == nullptr)
		{
			return;
		}
		cout << root->val;
		fprint(root->left);
		fprint(root->right);
	}
	bool find(const T& data)
	{
		if (root == nullptr)
		{
			return false;
		}
		node* cur = root;
		while (cur)
		{
			if (cur->val == data)
			{
				return true;
			}
			else if (cur->val > data)
			{
				cur = cur->left;
			}
			else
			{
				cur = cur->eight;
			}
		}
		return false;
	}
	bool erase(const T& key)
	{
		node* pcur = nullptr;
		node* cur = root;
		while (cur)
		{
			if (cur->val < key)
			{
				pcur = cur;
				cur = cur->right;
			}
			else if (cur->val > key)
			{
				pcur = cur;
				cur = cur->left;
			}
			else
			{
				if (cur->left == nullptr)
				{
					if (cur == root)
					{
						root = cur->right;
					}
					else
					{
						if (pcur->left == cur)
						{
							pcur->left = cur->right;
						}
						else
						{
							pcur->right = cur->right;
						}
					}
				}
				else if (cur->right == nullptr)
				{
					if (cur == root)
					{
						root = cur->left;
					}
					else
					{
						if (pcur->left = cur)
						{
							pcur->left = cur->left;
						}
						else
						{
							pcur->right = cur->left;
						}
					}
				}
				else
				{
					node* pminr = cur;
					node* minr = cur->right;
					while (minr->left)
					{
						pminr = minr;
						minr = minr->left;
					}
					cur->val = minr->val;
					if (pminr->left == minr)
					{
						if (pminr->right)
						{
							pminr->left = minr->right;
						}
						else
						{
							pminr->left = nullptr;
						}
					}
					else
					{
						if (pminr->left)
						{
							pminr->right = minr->right;
						}
						else
						{
							pminr->right = nullptr;
						}

					}
				
				}
				return true;
			}
		
		}
		return false;
	}
};

7.递归删除(递归插入和查找过于简单就不赘述了),思路和非递归一模一样只不过当交换值后换值的树不可避免的被弄乱,所以需要继续删除调整

struct BSTNode
{
	BSTNode<T> left;
	BSTNode<T>right;
	T val;
};
template<class T>
class bstree
{
	typedef BSTNode node;
	node* root = nullptr;
public:
	bool insert(const T&key)
	{
		if (root == nullptr)
		{
			root = new node(key);
			return true;
		}
		else
		{
			node* cur = root;
			node* pcur = nullptr;
			while (cur)
			{
				if (key > cur->val)
				{
					pcur = cur;
					cur = cur->right;
				}
				else if (key < cur->val)
				{
					pcur = cur;
					cur = cur->left;
				}
				else
				{
					return false;
				}
			}
			cur = new node(key);
			if (pcur->val < key)
			{
				cur = pcur->right;
				return true;
			}
			else
			{
				cur = pcur->left;
				return true;
			}
		}
	}
	void fprint(node* point = root)
	{
		if (root == nullptr)
		{
			return;
		}
		cout << root->val;
		fprint(root->left);
		fprint(root->right);
	}
	bool find(const T& data)
	{
		if (root == nullptr)
		{
			return false;
		}
		node* cur = root;
		while (cur)
		{
			if (cur->val == data)
			{
				return true;
			}
			else if (cur->val > data)
			{
				cur = cur->left;
			}
			else
			{
				cur = cur->eight;
			}
		}
		return false;
	}
	bool erase(const T& key)
	{
		node* pcur = nullptr;
		node* cur = root;
		while (cur)
		{
			if (cur->val < key)
			{
				pcur = cur;
				cur = cur->right;
			}
			else if (cur->val > key)
			{
				pcur = cur;
				cur = cur->left;
			}
			else
			{
				if (cur->left == nullptr)
				{
					if (cur == root)
					{
						root = cur->right;
					}
					else
					{
						if (pcur->left == cur)
						{
							pcur->left = cur->right;
						}
						else
						{
							pcur->right = cur->right;
						}
					}
				}
				else if (cur->right == nullptr)
				{
					if (cur == root)
					{
						root = cur->left;
					}
					else
					{
						if (pcur->left = cur)
						{
							pcur->left = cur->left;
						}
						else
						{
							pcur->right = cur->left;
						}
					}
				}
				else
				{
					node* pminr = cur;
					node* minr = cur->right;
					while (minr->left)
					{
						pminr = minr;
						minr = minr->left;
					}
					cur->val = minr->val;
					if (pminr->left == minr)
					{
						if (pminr->right)
						{
							pminr->left = minr->right;
						}
						else
						{
							pminr->left = nullptr;
						}
					}
					else
					{
						if (pminr->left)
						{
							pminr->right = minr->right;
						}
						else
						{
							pminr->right = nullptr;
						}

					}
				
				}
				return true;
			}
		
		}
		return false;
	}
	bool dpep(node* point, const T& key)
	{
		if (point == nullpty)
		{
			return false;
		}
		if (point->val < key)
		{
			return dpep(point->right, key);
		}
		else if (point->val > key)
		{
			return dpep(point->left, key)
			
		}
		else
		{
			if (point->left == nullptr)
			{
				node* cur = point->right;
				delete point;
				point = cur;
			}
			else if (point->right == nullptr)
			{
				node* cur = point->left;
				delete point;
				point = cur;
			}
			else
			{
				node* cur = point->left;
				while (cur->right)
				{
					cur = cur->right;
				}
				swap(point->val, cur->val);
				return dpep(point->left, key);
			}
			return true;
		}
	}
	bool dpe(const T&key)
	{
		return dpep(root, key);
	}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值