BST树基本操作

BST树的概念

一、二叉搜索树(binary search tree)即就是我们所说的BST树
二、BST树的特征:任何一个节点比它的左孩子大,比它的右孩子小,
如图所示就是一颗BST树
在这里插入图片描述
三、定义BST树的节点类型

struct BSTNode
	{
		BSTNode(T data = T())
			:_data(data)
			, _left(nullptr)
			, _right(nullptr)
		{}
		T _data;
		BSTNode *_left;
		BSTNode *_right;
	};

BST树的实现

BST树的插入操作

1、非递归实现BST树的插入操作

void noninsert(const T &val)
	{
		if (_root == nullptr)
		{
			_root = new BSTNode(val);
			return;
		}
		BSTNode* pre = nullptr;
		BSTNode * cur = _root;
		while (cur != nullptr)
		{
			pre = cur;
			if (val < cur->_data)
			{
				cur = cur->_left;
			}
			else if (val > cur->_data)
			{
				cur = cur->_right;
			}
			else
			{
				return;
			}
		}
		if (val < pre->_data)
		{
			pre->_left = new BSTNode(val);
		}
		else
		{
			pre->_right = new BSTNode(val);

		}
	}

2、递归实现BST树的插入

void insert(const T &val)
	{
		_root = insert(_root,val);
	}

BSTNode* insert(BSTNode * node, const T &val)
	{
		if (node == nullptr)
		{
			return new BSTNode(val);
		}

		if (val > node->_data)
		{
			node->_right = insert(node-_right,val);
		}
		else if (val < node->_data)
		{
			node->_left = insert(node->_left,val);
		}
		else
		{
			;
		}
		return node;
	}

3、非递归实现层序遍历,从根结点开始,一层一层从左向右遍历,相当于打印

void nonlevelOrder()
	{
		//1.如果_root为空,直接返回
		if (_root == nullptr)
			return;
		//2._root -> queue
		queue<BSTNode*> que;
		que.push(_root);
		//3.循环判断队列是否为空,不为空取出队头元素,分别判断左右孩子是否为空,不为空就要依次入队,然后打印队头元素,继续判断下一个队头元素
		
		while (!que.empty())
		{
			BSTNode *front = que.front();
			cout << front->_data << " ";
			que.pop();
			if (front->_left != nullptr)
			{
				que.push(front->_left);
			}
			if (front->_right != nullptr)
			{
				que.push(front->_right);
			}
		}

BST树的删除操作

1、删除操作分三种情况:
1)、删除的节点没有孩子节点
2)、删除的节点只有一个孩子节点
3)、删除的节点有两个孩子节点
2、非递归实现BST树的删除操作

void nonremove(const T &val)
	{
		//1.从_root开始寻找值为val的节点,cur指向它
		BSTNode *cur = _root;
		BSTNode *pre = nullptr;
		while (cur != nullptr)
		{
			if (val < cur->_data)
			{
				pre = cur;
				cur = cur->_left;
			}
			else if (val > cur->_data)
			{
				pre = cur;
				cur = cur->_right;

			}
			else
			{
				break;
			}
		}
		if (cur == nullptr)
			return;
		//2.先判断是否满足情况3,如果满足,需要找cur的前驱节点,用前驱把cur节点的值覆盖,直接删前驱
		//前驱节点:当前节点左子树中的最大值
		//后继节点:当前节点右子树元素中的最小值
		if (cur->_left != nullptr && cur->right != nullptr)
		{
			BSTNode *old = cur;
			pre = cur;
			cur = cur->_left;
			while (cur->_right != nullptr)
			{
				pre = cur;
				cur = cur->_right;
			}
			old->_data = cur->_data;//找到了cur的前驱节点把原来要删除的节点覆盖
		}
		//3.删除情况1和情况2  直接删除cur指针指向的节点就可以了
		BSTNode *child = cur ->_left;
		if (child == nullptr)
		{
			child = cur->_right;
		}
		if (pre == nullptr)//cur指向的根节点
		{
			_root = child;
		}
		else
		{
			//要把删除节点的孩子赋给cur父节点相应的地址域里面
			if (cur == pre->_left)
			{
				pre->_left = child;
			}
			else
			{
				pre->_right = child;
			}
		}

		delete cur;
	}

3、递归实现BST树的删除操作

void remove(const T &val)
	{
		_root = remove(_root,val);
	}

//以node 为根节点,递归实现BST树的删除操作,并返回其孩子节点的地址更新父节点相应地址域
	BSTNode *remove(BSTNode * node, const T &val)
	{
		if (node == nullptr)
			return nullptr;
		if (val < node->_data)
		{
			node->_left =  remove(node->_left,val);
		}
		else if (val > node->_data)
		{
			node->_right = remove(node->_right,val);
		}
		else
		{
			if (node->_left != nullptr && node->_right != nullptr);
			{
				BSTNode *pre = node->_left;
				while (pre->_right != nullptr)
				{
					pre = pre->_right;
				}
				node->_data = pre->_data;
				//直接删除前驱 node = remove(pre,pre->_data);
				node->_left = remove(node->_left, pre->_data);
			}
			else
			{
				if (node->_left != nullptr)
				{
					BSTNode *left = node->_left;
					delete node;
					return left;
				}
				else if (node->_right != nullptr)
				{
					BSTNode *right = node->_right;
					delete node;
					return right;
				}
				else
				{
					delete node;
					return nullptr;
				}
			}
		}
		
	}

BST树的查找

1、递归实现查询val的值,找到返回true,否则返回false

bool query(const T &val)
	{
		return query(_root,val);
	}

//以node为根节点开始搜索值为val的节点
	bool query(BSTNode * node, const T &val)
	{
		if (node == nullptr)
		{
			return false;
		}
		if (val > node->_data)
		{
			return query(node->_right,val);
		}
		else if (val < node->_data)
		{
			return query(node->_left, val);
		}
		else
		{
			return true;

		}

	}

BST树的遍历

BST有前序遍历(VLR)、中序遍历(LVR)、后序遍历(LRV)以及层序遍历。

BST树的前序遍历

1、递归实现前序遍历 根左右VLR

void preOrder()
	{
		cout << "递归实现前序遍历: ";
		preOrder(_root);
		cout << endl;
	}

//以node为根节点(v)前序遍历BST树
	void preOrder(BSTNode *node)
	{
		if (node != nullptr)
		{
			cout << node->_data << " "; //先打印根节点
			preOrder(node->_left); //以VLR的方式继续访问左孩子
			preOrder(node->_right);//以VLR的方式继续访问右孩子
		}
	}

BST树的中序遍历

//递归实现中序遍历 左根右 LVR
	void inOrder()
	{
		cout << "递归实现中序遍历:";
		inOrder(_root);
		cout << endl;

	}
	

//以node为根节点(v)中序遍历BST树 LVR
	void inOrder(BSTNode *node)
	{
		if (node != nullptr)
		{
			inOrder(node->_left);
			cout << node->_data << " ";
			inOrder(node->_right);
		}
	}

BST树的后序遍历

//递归实现后序遍历 左右根 LRV
	void postOrder()
	{
		cout << "递归实现后序遍历:";
		postOrder(_root);
		cout << endl;

	}

//以node为根节点(v)后序遍历BST树  LRV
	void postOrder(BSTNode *node)
	{
		if (node != nullptr)
		{
			postOrder(node->_left);
			postOrder(node->_right);
			cout << node->_data << " ";
		}

	}

BST树的层序遍历

//递归实现层序遍历
	void levelOrder()
	{
		cout << "递归实现层序遍历:";
		int l = level(_root);
		for (int i = 0; i < l; ++i)
		{
			 levelOrder(_root,i);
		}
		cout << endl;
	}

//打印以node为根节点的树的层序遍历
	void levelOrder(BSTNode *node, int k)
	{
		if (node != nullptr)
		{
			if (k == 0)
			{
				cout << node->_data << " ";
				return;
			}
			levelOrder(node->_left, k - 1);
			levelOrder(node->_right, k - 1);
		}
	}

BST树的一些常见题型

1、判断当前二叉树是不是一颗BST树

bool isBSTree()
	{
		BSTNode *pre = nullptr;
		return isBSTree(_root,pre);
	}

//以node为根节点判断当前BST树是不是一颗二叉树
	bool isBSTree(BSTNode *node, BSTNode *&pre)
	{
		if (node == nullptr)   
		{
			return true;
		}
		if (!isBSTree(node->_left, pre))
		{
			return false;
		}

		if (pre != nullptr)
		{
			if (node->_data < pre->_data)
			{
				return false;
			}
		}
		pre = node;

		return isBSTree(node->_right,pre);
	}

2、在当前BST树中,把满足区间[first,last]的所有元素找出来并打印
3、获取两个节点的最近公共祖先节点
4、获取中序遍历倒数第k个节点的值
5、已知一颗BST树的前序遍历结果pre数组,和中序遍历结果in数组,重建二叉树
等等,这都是BST树的经典题型题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值