二叉搜索树(Binary Search Tree)

二叉搜索树概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

它的左右子树也分别为二叉搜索树

二叉搜索树操作

1. 二叉搜索树的查找

a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。

b、最多查找高度次,走到到空,还没找到,这个值不存在。

2. 二叉搜索树的插入 插入的具体过程如下:

a. 树为空,则直接新增节点,赋值给root指针

b. 树不空,按二叉搜索树性质查找插入位置,插入新节点

3. 二叉搜索树的删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情 况:

a. 要删除的结点无孩子结点

b. 要删除的结点只有左孩子结点

c. 要删除的结点只有右孩子结点

d. 要删除的结点有左、右孩子结点

看起来有待删除节点有4种情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程 如下:

情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除

情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除

情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点 中,再来处理该结点的删除问题--替换法删除

搜索二叉树(包括递归版和非递归版)

#pragma once
#include<iostream>
#include<string>
using namespace std;

//搜索二叉树节点
template<class K>
struct BSTreeNode
{
	BSTreeNode* left;
	BSTreeNode* right;
	K key;

	BSTreeNode(const K& k)
		:left(nullptr)
		, right(nullptr)
		, key(k)
	{}
};


namespace K
{
	template<class K>
	class BSTree
	{
	public:
		typedef BSTreeNode<K> node;
		
		BSTree()
		{}

		BSTree(const BSTree<K>& x)
		{
			_root = copy(x._root);
		}

		BSTree<K>& operator=(BSTree<K> x)
		{
			swap(_root, x._root);
			return *this;
		}

		~BSTree()
		{
			destroy(_root);
			_root = nullptr;
		}


		bool insert(const K& k)
		{
			if (_root == nullptr)
			{
				node* newnode = new node(k);
				_root = newnode;
				return true;
			}

			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (cur->key == k)
				{
					return false;
				}
				else if (cur->key > k)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (cur->key < k)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			node* newnode = new node(k);
			if (parent->key > k)
			{
				parent->left = newnode;
			}
			else if (parent->key < k)
			{
				parent->right = newnode;
			}
			return true;
		}

		node* find(const K& k)
		{
			node* cur = _root;
			while (cur)
			{
				if (k == cur->key)
				{
					return cur;
				}
				else if (k < cur->key)
				{
					cur = cur->left;
				}
				else if (k > cur->key)
				{
					cur = cur->right;
				}
			}

			return nullptr;
		}

		void inorder()
		{
			_inorder(_root);
			cout << endl;
		}

		bool erase(const K& k)
		{
			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (k == cur->key)
				{
					break;
				}
				else if (k < cur->key)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (k > cur->key)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			if (cur == nullptr)
			{
				return false;
			}

			if (cur->left == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if(k < parent->key)
				{
					parent->left = cur->right;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->right;
					delete cur;
				}
			}
			else if (cur->right == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if (k < parent->key)
				{
					parent->left = cur->left;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->left;
					delete cur;
				}
			}
			else
			{
				node* pre = cur;
				node* right_min = cur->right;
				while (right_min->left)
				{
					pre = right_min;
					right_min = right_min->left;
				}
				swap(cur->key, right_min->key);
				if (pre == cur)
				{
					pre->right = right_min->right;
				}
				else
				{
					pre->left = right_min->right;
				}
				delete right_min;

			}
			return true;
		}

		///
		//递归版本
		bool insertR(const K& k)
		{
			return _insertR(_root, k);
		}

		node* findR(const K& k)
		{
			return _findR(_root, k);
		}

		bool eraseR(const K& k)
		{
			return _eraseR(_root, k);
		}


	protected:
		void _inorder(const node* n)
		{
			if (n == nullptr)
				return;

			_inorder(n->left);
			cout << n->key << "  ";
			_inorder(n->right);
		}

		node* copy(node* root)
		{
			if (root == nullptr)
			{
				return nullptr;
			}

			node* newnode = new node(root->key);
			newnode->left = copy(root->left);
			newnode->right = copy(root->right);
			return newnode;
		}

		void destroy(node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			destroy(root->left);
			destroy(root->right);
			delete root;
		}

		bool _insertR(node*& root, const K& k)
		{
			if (root == nullptr)
			{
				root = new node(k);
				return true;
			}
			else if (k == root->key)
			{
				return false;
			}
			else if (k < root->key)
			{
				return _insertR(root->left, k);
			}
			else
			{
				return _insertR(root->right, k);
			}
		}

		node* _findR(node* root,const K& k)
		{
			if (root == nullptr)
			{
				return nullptr;
			}
			if (k == root->key)
			{
				return root;
			}
			else if (k < root->key)
			{
				return _findR(root->left, k);
			}
			else
			{
				return _findR(root->right, k);
			}
		}

		bool _eraseR(node*& root,const K& k)
		{
			if (root == nullptr)
			{
				return false;
			}
			if (k < root->key)
			{
				return _eraseR(root->left, k);
			}
			else if (k > root->key)
			{
				return _eraseR(root->right, k);
			}
			else
			{
				node* del = root;
				if (root->left == nullptr)
				{
					root = root->right;
					delete del;
				}
				else if (root->right == nullptr)
				{
					root = root->left;
					delete del;
				}
				else
				{
					node* minRight = root->right;
					while (minRight->left)
					{
						minRight = minRight->left;
					}
					swap(root->key, minRight->key);
					return _eraseR(root->right, k);
				}
				return true;
			}
		}

		node* _root = nullptr;
	};

}

搜索二叉树(KV版)

namespace KV
{

	template<class K, class V>
	struct BSTreeNode
	{
		BSTreeNode* left;
		BSTreeNode* right;
		K key;
		V val;

		BSTreeNode(const K& k, const V& v)
			:left(nullptr)
			, right(nullptr)
			, key(k)
			, val(v)
		{}
	};

	template<class K, class V>
	class BSTree
	{
	public:
		typedef BSTreeNode<K, V> node;

		BSTree()
		{}

		BSTree(const BSTree<K, V>& x)
		{
			_root = copy(x._root);
		}

		BSTree<K, V>& operator=(BSTree<K, V> x)
		{
			swap(_root, x._root);
			return *this;
		}

		~BSTree()
		{
			destroy(_root);
			_root = nullptr;
		}


		bool insert(const K& k,const V& v)
		{
			if (_root == nullptr)
			{
				node* newnode = new node(k, v);
				_root = newnode;
				return true;
			}

			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (cur->key == k)
				{
					return false;
				}
				else if (cur->key > k)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (cur->key < k)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			node* newnode = new node(k, v);
			if (parent->key > k)
			{
				parent->left = newnode;
			}
			else if (parent->key < k)
			{
				parent->right = newnode;
			}
			return true;
		}


		void inorder()
		{
			_inorder(_root);
			cout << endl;
		}

		bool erase(const K& k)
		{
			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (k == cur->key)
				{
					break;
				}
				else if (k < cur->key)
				{
					parent = cur;
					cur = cur->left;
				}
				else if (k > cur->key)
				{
					parent = cur;
					cur = cur->right;
				}
			}
			if (cur == nullptr)
			{
				return false;
			}

			if (cur->left == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if (k < parent->key)
				{
					parent->left = cur->right;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->right;
					delete cur;
				}
			}
			else if (cur->right == nullptr)
			{
				if (parent == nullptr)
				{
					delete cur;
					_root = nullptr;
				}
				else if (k < parent->key)
				{
					parent->left = cur->left;
					delete cur;
				}
				else if (k > parent->key)
				{
					parent->right = cur->left;
					delete cur;
				}
			}
			else
			{
				node* pre = cur;
				node* right_min = cur->right;
				while (right_min->left)
				{
					pre = right_min;
					right_min = right_min->left;
				}
				swap(cur->key, right_min->key);
				swap(cur->val, right_min->val);
				if (pre == cur)
				{
					pre->right = right_min->right;
				}
				else
				{
					pre->left = right_min->right;
				}
				delete right_min;

			}
			return true;
		}

		node* Find(const K& k)
		{
			node* cur = _root;
			while (cur)
			{
				if (cur->key < k)
				{
					cur = cur->right;
				}
				else if (cur->key > k)
				{
					cur = cur->left;
				}
				else
				{
					return cur;
				}
			}

			return nullptr;
		}

	protected:
		void _inorder(const node* n)
		{
			if (n == nullptr)
				return;

			_inorder(n->left);
			cout << n->key << "  " << n->val << "  ";
			_inorder(n->right);
		}

		node* copy(node* root)
		{
			if (root == nullptr)
			{
				return nullptr;
			}

			node* newnode = new node(root->key,root->val);
			newnode->left = copy(root->left);
			newnode->right = copy(root->right);
			return newnode;
		}

		void destroy(node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			destroy(root->left);
			destroy(root->right);
			delete root;
		}

		
		node* _root = nullptr;
	};

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 二叉搜索树Binary Search Tree):是一棵空树或者具有下列性质的二叉树:若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;它的左右子树也分别为二叉搜索树。 中序遍历序列:对于任意一棵二叉树,中序遍历的结果都是一个序列,这个序列称为中序遍历序列。 因此,判断一棵二叉树是否为二叉搜索树,可以先进行中序遍历,再判断遍历结果是否为升序序列。 以下是 Python 代码实现: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def inorderTraversal(root: TreeNode) -> List[int]: res = [] if not root: return res res.extend(inorderTraversal(root.left)) res.append(root.val) res.extend(inorderTraversal(root.right)) return res def isBST(root: TreeNode) -> bool: res = inorderTraversal(root) for i in range(1, len(res)): if res[i] <= res[i-1]: return False return True ``` 其中,`TreeNode` 是二叉树的节点类,`inorderTraversal` 函数是实现二叉树中序遍历的递归函数,`isBST` 函数是判断二叉树是否为二叉搜索树的函数。 ### 回答2: 要实现这个函数,首先我们可以使用递归的方式对二叉树进行中序遍历,即先遍历左子树,再访问根节点,最后遍历右子树。遍历过程中将遍历到的节点值保存到一个数组中。 接下来,我们需要判断该数组是否是按升序排列的,即判断是否是一棵二叉搜索树。我们可以遍历数组,依次比较相邻的节点值,如果前一个节点的值大于等于后一个节点的值,则认为不是二叉搜索树。反之,如果整个数组都符合这个条件,则认为是一个二叉搜索树。 以下是一个简单的实现代码: ``` class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def inorderTraversal(root): if not root: return [] result = [] inorder(root, result) return result def inorder(root, result): if not root: return inorder(root.left, result) result.append(root.val) inorder(root.right, result) def isBST(root): inorder_result = inorderTraversal(root) for i in range(1, len(inorder_result)): if inorder_result[i] <= inorder_result[i-1]: return False return True ``` 这个函数的时间复杂度是O(n),其中n是二叉树中节点的数量,因为我们需要遍历每个节点并将节点的值保存到数组中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JDSZGLLL

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

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

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

打赏作者

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

抵扣说明:

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

余额充值