[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现

这篇具有很好参考价值的文章主要介绍了[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法

1、二叉搜索树

1.1 二叉搜索数的概念

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

  • 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  • 它的左右子树也分别为二叉搜索树
    我们先给出两个示例:
    [数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法
    此二叉树就不是搜索二叉树,根据性质来看,每颗子树也是二叉搜索树,红圈圈起来的地方显然是违背了这个性质。
    [数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法
    此搜索二叉树按性质来看是完全满足的,因此此二叉树就是二叉搜索树。

1.2 二叉搜索树的操作

二叉搜索树的操作包含,增删查,下面我们就来分别模拟实现这些接口。

1.2.1 二叉搜索树的查找

思路:
a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。
b、最多查找高度次,走到到空,还没找到,这个值不存在。
查找比较好理解,这里就不画图了,直接开始写代码。
1.查找的非递归方法:

bool Find(const K& key)
{
    Node* root = _root;
    while (root)
    {
        if (key > root->_key)
            root = root->_right;
        else if (key < root->_key)
            root = root->_left;
        else
            return true;
    }
    return false;
}

2.查找的递归方法:

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

bool _FindR(Node* root, const K& key)
{
    if (nullptr == root)
        return false;

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

在递归查找中,我们用户在使用的时候只需要填入要查找的数字,但是我们的查找接口需要两个参数,开始节点与查找数值,因此我们在 FindR 下再封装一层 _FindR 就可以实现了。

1.2.2 二叉搜索树的插入

二叉搜索树的插入思路:
a. 树为空,则直接新增节点,赋值给root指针
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点
我们先来以图例演示一遍过程:
对下面这棵树插入一个值为11的节点
[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法

这里是成功插入的情况,具体过程是上面的图例,我们在梳理一遍:
1、首先,我们用两个结点指针 parent和cur ,cur不断寻找正确插入位置,parent不断记下来cur的父节点指针;
2、当 cur 找到正确位置之后,先 new 一个节点对象给 cur,此时 new 出来的对象只是给了 cur 这个指针变量,并没有链接起来;
3、判断要插入的位置是 parent 的左孩子还是右孩子,再将其链接到正确位置插入就算完成了。
失败情况:
因为是二叉搜索树,节点左子树的值全小于节点的值,右子树的值全大于节点的值,不存在相等的情况,因此当找到一个节点的值与要插入的值相等时,就是插入失败,此时返回false。
根据上面的图示以及过程的梳理我们来写非递归版本的代码:

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

    Node* parent = nullptr;
    Node* cur = _root;
    while (cur)
    {
        if (key > cur->_key)
        {
            parnet = cur;
            cur = cur->_right;
        }
        else if (key < cur->_key)
        {
            parent = cur;
            cur = cur->_left;
        }
        else
        {
            return false;
        }
    }

    cur = new Node(key);
    if (key > parent->_key)
    {
        parent->_right = cur;
    }
    else
    {
        parent->_left = cur;
    }
    return true;
}

insert接口我们只提供非递归版本的。

1.2.3 二叉搜索树的删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情
况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点

看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程
如下:
情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点–直接删除
情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点–直接删除
情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点
中,再来处理该结点的删除问题–替换法删除
1、删除节点没有左孩子

[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法

// 1、左为空
if (cur->_left == nullptr)
{
    if (cur == _root)
    {
        _root = cur->_right;
    }
    
    if (parent->_left == cur)
    {
        parent->_left = cur->_right;
    }
    else
    {
        parent->_right = cur->_right;
    }
}

2、删除节点没有右孩子
[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法

// 2、右为空
else if (cur->_right == nullptr)
{
    if (cur == _root)
    {
        _root = cur->_left;
    }		

    if (parent->_left == cur)
    {
        parent->_left = cur->_left
    }
    else
    {
        parent->_right = cur->_left;
    }
}

3、删除节点左右孩子都存在
[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法

// 3、左右都不为空
else
{
    Node* parent = cur;
    Node* subLeft = cur->_right;
    while (subLeft->_left)
    {
        parent = subLeft;
        subLeft = subLeft->_left;
    }

    swap(cur->_key, subLeft->_key);
    
    if (subLeft == parent->_left)
        parent->_left = subLeft->_right;
    else
        parent->_right = subLeft->_right;

    delete(subLeft);
}

整个删除接口合在一起的代码:

bool Erase(const K& key)
{
    Node* parent = nullptr;
    Node* cur = _root;
    while (cur)
    {
        if (key > cur->_key)
        {
            parnet = cur;
            cur = cur->_right
        }
        else if (key < cur->_key)
        {
            parent = cur;
            cur = cur->_left;
        }
        else
        {
            // 1、左为空
            if (cur->_left == nullptr)
            {
                if (cur == _root)
                {
                    _root = cur->_right;
                }

                if (parent->_left == cur)
                {
                    parent->_left = cur->_right;
                }
                else
                {
                    parent->_right = cur->_right;
                }
                delete(cur);
            }
            // 2、右为空
            else if (cur->_right == nullptr)
            {
                if (cur == _root)
                {
                    _root = cur->_left;
                }		

                if (parent->_left == cur)
                {
                    parent->_left = cur->_left
                }
                else
                {
                    parent->_right = cur->_left;
                }
                delete(cur);
            }
            // 3、左右都不为空
            else
            {
                Node* parent = cur;
                Node* subLeft = cur->_right;
                while (subLeft->_left)
                {
                    parent = subLeft;
                    subLeft = subLeft->_left;
                }

                swap(cur->_key, subLeft->_key);
                
                if (subLeft == parent->_left)
                    parent->_left = subLeft->_right;
                else
                    parent->_right = subLeft->_right;

                delete(subLeft);
            }
        }
    }	
}

递归版本:
递归版本与非递归版本类似, 非递归版本中使用while循环来找key位置,递归就是不断调用自身来找key位置当找到后依然分三种情况来分析:左为空、右为空、左右都不为空。
递归版本中用引用来接受传来的root,因此不用考虑链接问题也就不存在判断删除位置是父节点的左还是右,直接修改root即可。
1、左为空/左右都为空:先记下要删除的节点,再修改root,最后释放删除的节点。 Node* del = root; root = root->_right; delete(del);
2、右为空:先记下要删除的节点,再修改root,最后释放删除的节点。Node* del = root; root = root->_left; delete(del);
3、左右都不为空:先找到右子树的最左节点(最小值),交换 root->_key与subLeft->_key, 右子树的最左节点一定是叶子节点,因此删除subLeft直接再去调用函数自身即可,即再来一次左右都为空(左为空)的删除。

bool EraseR(const K& key)
{
    return _EraseR(_root, key);
}
bool _EraseR(Node*& root, const K& key)
{
    if (root == nullptr)
        return false;

    if (root->_key < key)
    {
        _EraseR(root->_right, key);
    }
    else if (root->_key > key)
    {
        _EraseR(root->_left, key);
    }
    else
    {
        if (root->_left == nullptr)
        {
            Node* del = root;
            root = root->_right;
            delete(del);// 必须释放,不释放会导致内存泄漏
            return true;
        }
        else if (root->_right == nullptr)
        {
            Node* del = root;
            root = root->_left;
            delete(del);
            return true;
        }
        else
        {
            Node* subLeft = root->_right;
            while (subLeft->_left)
            {
                subLeft = subLeft->_left;
            }

            swap(root->_key, subLeft->_key);

            return _EraseR(root->_right, key);
        }
    }
}

2、二叉搜索树的应用

2.1 K模型

K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。
比如:给一个单词word,判断该单词是否拼写正确,具体方式如下:

  • 以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树
  • 在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。

2.2 KV模型

KV模型:每一个关键码key,都有与之对应的值Value,即<Key, Value>的键值对。 该种方式在现实生活中非常常见:
● 比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文<word, chinese>就构成一种键值对;
● 再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是<word, count>就构成一种键值对。

3、二叉搜索树的性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。
但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:
[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现,C++,数据结构,c++,算法
最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其平均比较次数为:log_2 N
最差情况下,二叉搜索树退化为单支树(或者类似单支),其平均比较次数为:N

最差情况是退化为单支树,性能就变得很差了,因为后续我们将改进搜索二叉树的插入与删除,来实现平衡二叉搜索树,即AVL树与红黑树(RB树)。文章来源地址https://www.toymoban.com/news/detail-760348.html

4、K模型与KV模型完整代码

4.1 二叉搜索树的模拟实现(K模型)

namespace key
{
	template <class K>
	struct BSTreeNode
	{
		BSTreeNode* _left;
		BSTreeNode* _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 < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}
			return true;
		}

		bool Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return true;
				}
			}
			return true;
		}

		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
				{
					// 删除分情况讨论:
					// 1. 左为空(左右都为空);2. 右为空;3.左右都不为空
					if (cur->_left == nullptr)// 左为空
					{
						if (cur == _root)// 根节点是删除的节点情况
							_root = cur->_right;
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}
						delete(cur);
					}
					else if (cur->_right == nullptr)// 右为空
					{
						if (cur == _root)// 根节点是删除的节点情况
							_root = cur->_left;
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}
						delete(cur);
					}
					else// 左右都不为空
					{
						// 替换法,找左子树最大 / 右子树最小来替换cur
						Node* parent = cur;
						Node* subLeft = cur->_right;
						while (subLeft->_left)
						{
							parent = subLeft;
							subLeft = subLeft->_left;
						}

						swap(cur->_key, subLeft->_key);

						if (subLeft == parent->_left)
							parent->_left = subLeft->_right;
						else// 处理删除根节点的情况
							parent->_right = subLeft->_right;

						delete(subLeft);
					}
					return true;
				}
			}
			return false;
		}

		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}

		//递归
		bool InsertR(const K& key)
		{
			return _InsertR(_root, key);
		}

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

		bool EraseR(const K& key)
		{
			return _EraseR(_root, key);
		}

		// C++11
		BSTree() = default; // 强制编译器生成默认构造

		BSTree(const BSTree<K>& t)
		{
			_root = Copy(t._root);
		}

		// 赋值重载,现代写法
		BSTree<K>& operator=(BSTree<K> t)
		{
			swap(_root, t._root);
			return *this;
		}

		~BSTree()
		{
			Destroy(_root);
		}

	private:
		Node* Copy(Node* root)
		{
			if (root == nullptr)
				return nullptr;

			Node* newRoot = new Node(root->_key);
			newRoot->_left = Copy(root->_left);
			newRoot->_right = Copy(root->_right);

			return newRoot;
		}

		void Destroy(Node*& root)
		{
			if (root == nullptr)
				return;

			Destroy(root->_left);
			Destroy(root->_right);
			delete root;
			root = nullptr;
		}

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

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

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

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

		bool _EraseR(Node*& root, const K& key)
		{
			if (root == nullptr)
				return false;

			if (root->_key < key)
			{
				_EraseR(root->_right, key);
			}
			else if (root->_key > key)
			{
				_EraseR(root->_left, key);
			}
			else
			{
				if (root->_left == nullptr)
				{
					Node* del = root;
					root = root->_right;
					delete(del);// 必须释放,不释放会导致内存泄漏
					return true;
				}
				else if (root->_right == nullptr)
				{
					Node* del = root;
					root = root->_left;
					delete(del);
					return true;
				}
				else
				{
					Node* subLeft = root->_right;
					while (subLeft->_left)
					{
						subLeft = subLeft->_left;
					}

					swap(root->_key, subLeft->_key);

					return _EraseR(root->_right, key);
				}
			}
		}

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

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

	private:
		Node* _root = nullptr;
	};
};

4.2 KV模型的模拟实现

namespace kv
{
	template <class K, class V>
	struct BSTreeNode
	{
		BSTreeNode<K, V>* _left;
		BSTreeNode<K, V>* _right;
		K _key;
		V _val;

		BSTreeNode(const K& key, const V& val)
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
			, _val(val)
		{}
	};

	template <class K, class V>
	class BSTree
	{
		typedef BSTreeNode<K, V> Node;
	public:
		bool Insert(const K& key, const V& val)
		{
			if (_root == nullptr)
			{
				_root = new Node(key, val);
				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, val);
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}
			return true;
		}

		Node* Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > 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
				{
					// 删除分情况讨论:
					// 1. 左为空(左右都为空);2. 右为空;3.左右都不为空
					if (cur->_left == nullptr)// 左为空
					{
						if (cur == _root)// 根节点是删除的节点情况
							_root = cur->_right;
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}
						delete(cur);
					}
					else if (cur->_right == nullptr)// 右为空
					{
						if (cur == _root)// 根节点是删除的节点情况
							_root = cur->_left;
						else
						{
							if (cur == parent->_left)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}
						delete(cur);
					}
					else// 左右都不为空
					{
						// 替换法,找左子树最大 / 右子树最小来替换cur
						Node* parent = cur;
						Node* subLeft = cur->_right;
						while (subLeft->_left)
						{
							parent = subLeft;
							subLeft = subLeft->_left;
						}

						swap(cur->_key, subLeft->_key);

						if (subLeft == parent->_left)
							parent->_left = subLeft->_right;
						else// 处理删除根节点的情况
							parent->_right = subLeft->_right;

						delete(subLeft);
					}
					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 << " : " << root->_val << endl;
			_InOrder(root->_right);
		}

	private:
		Node* _root = nullptr;
	};
};

到了这里,关于[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构——二叉搜索树(附带C++实现版本)

    二叉搜索树又叫二叉排序树 ,二叉搜索树也是一种树形结构。 它是一课满足以下性质的搜索树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别是二叉搜索树 注意,二

    2024年02月12日
    浏览(29)
  • 【数据结构】—搜索二叉树(C++实现,超详细!)

                                                           🎬 慕斯主页 : 修仙—别有洞天                                                        ♈️ 今日夜电波 :消えてしまいそうです—真夜中                                              

    2024年02月05日
    浏览(31)
  • C++------利用C++实现二叉搜索树【数据结构】

    什么是二叉搜索树,二叉搜索树就是指左孩子永远比根小右孩子永远比根大。这个规则适用于所有的子树。 上面的就是一棵二叉搜索树,我们还可以发现这棵树走一个中序遍历序列是有序的,所以它又被称为二叉排序树。 二叉搜索树的操作主要分为以下几点,查找, 插入,

    2024年02月11日
    浏览(32)
  • 数据结构之进阶二叉树(二叉搜索树和AVL树、红黑树的实现)超详细解析,附实操图和搜索二叉树的实现过程图

    绪论​ “生命有如铁砧,愈被敲打,愈能发出火花。——伽利略”;本章主要是数据结构 二叉树的进阶知识,若之前没学过二叉树建议看看这篇文章一篇掌握二叉树,本章的知识从浅到深的 对搜索二叉树的使用进行了介绍和对其底层逻辑的实现进行了讲解 ,希望能对你有所

    2024年02月04日
    浏览(36)
  • C++数据结构之平衡二叉搜索树(一)——AVL的实现(zig与zag/左右双旋/3+4重构)

    本文是介绍众多平衡二叉搜索树(BBST)的第一篇——介绍AVL树。故先来引入BBST的概念。由于上一篇介绍的二叉搜索树(BST)在极度退化的情况下,十分不平衡,不平衡到只朝一侧偏,成为一条链表,复杂度可达 O ( n ) O(n) O ( n ) ,所以我们要在“平衡”方面做一些约束,以防

    2024年02月13日
    浏览(24)
  • 【C++&数据结构】超详细一文带小白轻松全面理解 [ 二叉搜索树 ]—— [从零实现&逐过程分析&代码演示&简练易懂](23)

    前言 大家好吖,欢迎来到 YY 滴数据结构系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《初

    2024年02月05日
    浏览(92)
  • 数据结构---二叉搜索树

    二叉搜索树(Binary Search Tree 简称BST)又称二叉排序树,是一种二叉树的特殊形式,它在每个节点上存储的键值满足以下性质: 若它的左子树不为空,则左子树上的所有节点的 值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也

    2024年02月07日
    浏览(31)
  • 【数据结构】二叉搜索树

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

    2024年01月19日
    浏览(29)
  • [数据结构]-二叉搜索树

    前言 作者 : 小蜗牛向前冲 名言 : 我可以接受失败,但我不能接受放弃   如果觉的博主的文章还不错的话,还请 点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 目录 一、二叉搜索树的基本知识 1、什么是二叉搜索树 2、二叉搜索树的性能

    2024年02月08日
    浏览(35)
  • 数据结构——二叉搜索树

    本章代码:二叉搜索树 二叉搜索树又叫二叉排序树,它具有以下性质: 若左子树不为空,则左子树上所有结点的值都小于根结点的值 若右子树不为空,则右子树上所有结点的值都大于根结点的值 它的左右子树也分别为二叉搜索树 这个结构的时间复杂度为一般人会以为是 O(

    2024年02月12日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包