二叉搜索树

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

二叉搜索树的 中序遍历是单调递增的:

二叉搜索树---搜索节点

从树根出发,逐步地缩小查找范围,直到发现目标(成功)或缩小至空树(失败)

 在上树中搜索22的过程如下:

首先,经与根节点 16比较确认目标关键 码更大,故深入右子树 25递归查找;经比较发 现目标关键码更小,故 继续深入左子树19递 归查找;经再次比较确 认目标关键码更大后, 深入右子树22递归查 找;最终在节点22处匹 配,查找成功。

如果搜索到空还没有找到,则查找失败。

二叉搜索树---插入节点

1.树为空,则直接插入
2.树不为空,按二叉搜索树性质查找插入位置,插入新节点,查找插入位置的思想和搜索节点类似
二叉搜索树---删除节点
首先查找元素是否在二叉搜索树中,如果不存在,则返回
若存在,要删除的结点可能分下面几种情况
1.若要删除叶节点,直接删除
2.若要删除的节点只有左子树或右子树,删除该节点,并用子树代替空出的位置
3.若要删除的节点左右子树都存在,找到该节点的直接后继节点(中序遍历的下一个,即右子树的值最小的节点),交换两节点的值,删除目标节点( 因为是右树最小值,故无左孩子),其子树替代方法 同1和2
C++实现二叉搜索树:
#include<iostream>
using namespace std;

template<class K>
struct BSTreeNode
{
	BSTreeNode<K> * _left;
	BSTreeNode<K> * _right;
	K _key;

	BSTreeNode(const K& key)
		: _left(nullptr)
		, _right(nullptr)
		, _key(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 < cur->_key)
			parent->_right = cur;
		else
			parent->_left = cur;

		return true;
	}
	Node* Find(const K& key)
	{

		Node* cur = _root;
		while (cur)
		{
			if (key > cur->_key)
				cur = cur - > right;
			else if (key < cur->_key)
				cur = cur->left;
			else
				return cur;
		}
		return nullptr;
	}
	bool Erase(const K& key)
	{

		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
			{
				if (cur->_left == nullptr)
				{
					if (cur == parent->_left)
						parent->_left = cur->_right;
					else
						parent->_right = cur->_right;
					delete cur;
					return true;
				}
				else if (cur->_right == nullptr)
				{
					if (cur == parent->_left)
						parent->_left = cur->_left;
					else
						parent->_right = cur->_left;
					delete cur;
					return true;
				}
				else
				{
					Node* next = cur->_right;
					Node* pnext = cur;
					while (next->_left)
					{
						pnext = next;
						next = next->_left;
					}

					cur->_key = next->_key;

					if (next == pnext->_left)
						pnext->_left = next->_right;
					else
						pnext->_right = next->_right;

					delete next;
					return true;
				}
			}
		}
		return false;
	}
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}

private:
	void _InOrder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}

		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}


private:
	Node* _root = nullptr;
};
int main()
{
	int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	BSTree<int> t;
	for (auto e : a)
	{
		t.Insert(e);
	}
	t.InOrder();

	t.Erase(7);
	t.InOrder();

	t.Erase(5);
	t.InOrder();
	return 0;
}

测试结果:

( 本文图示部分参自《数据结构》邓俊辉 )

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南无故人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值