【C++】二叉搜索树

目录

1. 二叉搜索数概念

2. 二叉搜索树模拟实现

2.1 树节点类初始结构

2.2 树类初始结构

2.3 Insert(插入)

2.5 Find(查找)

2.6 Erase(删除)

2.7 中序遍历 

2.8 析构

2.9 拷贝构造

2.10 赋值重载

3. 二叉搜索树的性能

4. 二叉搜索树的应用 

5. 编程题

5.1  二叉树的最近公共祖先

5.2 二叉搜索树与双向链表

5.3 从前序与中序遍历序列构造二叉树

5.4 二叉树的前序遍历(非递归版本)


1. 二叉搜索数概念

2. 二叉搜索树模拟实现

2.1 树节点类初始结构

1. 一个指针指向左子树。

2. 一个指针指向右子树。

3. 一个变量存放数据。 

4. 构造函数:传入数据,初始化列表进行初始化。

template<class K>
struct BSTreeNode
{
	//左右指向和数据
	BSTreeNode<K>* _left;
	BSTreeNode<K>* _right;
	K _key;

	//构造
	BSTreeNode(const K& key)
		:_left(nullptr)
		,_right(nullptr)
		,_key(key)
	{}
};

2.2 树类初始结构

1. 私有成员变量只有一个根节点的指针。 

2.3 Insert(插入)

1. 如果树为空,那么用待插入的值创建节点作为根节点。插入成功返回true。

2. 如果树不为空,用cur标记根节点的位置,插入的值和cur位置的值比较,比你大,cur就去右边,比你小,cur就去左边,继续比较,直到cur走到空,就在cur位置创建一个节点。连接的话需要一个前驱指针,每次cur移动之前赋值给前驱指针。

3. 如果值相等就不插入,返回false。

4. 创建完新节点后需要判断插入在上面节点的哪一边,用值比较,如果比上面大就插在右边,小就插在左边。 

	bool Insert(const K& key)
	{
		//判空
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}

		Node* cur = _root;
		Node* prev = nullptr;
		//找位置
		while (cur)
		{
			prev = cur;

			if (key > cur->_key)
			{
				cur = cur->_right;
			}
			else if (key < cur->_key)
			{
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}

		//建节点
		cur = new Node(key);
		if (key > prev->_key)
		{
			prev->_right = cur;
		}
		else
		{
			prev->_left = cur;
		}
		return true;
	}

【递归版本】

1. 从根节点开始比较,你比我大就去我的右子树,你比我小就去我的左子树,相等就不插入,走到空就插入,参数是节点的引用。

	bool InsertR()
	{
		return _InsertR(_root);
	}

	bool _InsertR(Node*& root, const K& key)
	{
		//结束条件
		if (root == nullptr)
		{
			root = new Node(key);
			return true;
		}

		//找位置
		if (key > root->_key)
		{
			return _InsertR(root->_right, key);
		}
		else if(key < root->_key)
		{
			return _InsertR(root->_left, key);
		}
		else
		{
			return false;
		}
	}

2.5 Find(查找)

1. 值比较,从根节点开始比,比你小就继续往左边比,比你大就往右边,遇到相等就是找到了,走到空就是没有。 

	bool 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 true;
			}
		}
		return false;
	}

【递归版本】

1. 比我小就去我的左子树找,比我大就去我的右子树找,相等就返回true,找到空就返回false。

	bool FindR(const K& key)
	{
		return _FindR(_root, key);
	}

	bool _FindR(Node* root, const K& key)
	{
		//结束条件
		if (root == nullptr)
		{
			return false;
		}

		if (key > root->_key)
		{
			return _FindR(root->_right, key);
		}
		else if (key < root->_key)
		{
			return _FindR(root->_left, key);
		}
		else
		{
			return true;
		}
	}

2.6 Erase(删除)

删除的节点有四种情况:

a:节点无孩子

b:节点有左孩子

c:节点有右孩子

d:节点有两个孩子

1. 先找到要删除的节点,记录前驱指针。

2. 如果删除的节点左为空,那么前驱指针指向这个节点的右,释放这个节点,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值