您的位置:首页 > 房产 > 家装 > 【C++】二叉搜索树

【C++】二叉搜索树

2024/10/6 6:00:09 来源:https://blog.csdn.net/m0_73911405/article/details/142183725  浏览:    关键词:【C++】二叉搜索树

二叉搜索树

【概念】

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

  • 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  • 它的左右子树也分别为二叉搜索树

先定义二叉树的结构

struct BSTreeNode
{K _key;BSTreeNode<K>* _left;BSTreeNode<K>* _right;BSTreeNode(const K& key):_key(key),_left(nullptr),_right(nullptr){}
};

 利用二叉树结构模拟实现二叉搜索树

template<class K>
class BSTree
{typedef BSTreeNode<K> Node;
private:Node* _root = nullptr;
};

1. 二叉搜索树的插入

插入时要先判断_root是不是空节点

其次插入一个数(key)时要判断头结点与key的大小,大则往右树走,小则左树。再依次遍历判断。

最后判断要在父节点的哪个位置

	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 true;}}cur = new Node(key);if (parent->_key < key){parent->_right = cur;}else {parent->_left = cur;}return true;}

2. 搜索二叉树

本质上就是遍历 

	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 false;}

 3. 中序遍历

中序遍历就是左子树,根,右子树。

采用递归思想。

	void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}

当我们在main函数使用中序遍历时,发现传递不了root根节点。这时,我们把_InOrder设置为私有函数。在公有函数中引用私有函数_InOrder

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

4. 删除二叉树

 删除二叉树中的节点

如果删除叶子节点,直接删除

如果删除只有一个子节点的节点,则需要把他的父节点与他的子节点链接

如果删除有两个节点的节点,则需要找一个节点替代  左子树的最大 或 右子树最小

无子节点或者有一个子节点可以归为一类,我们只需把有一个子节点的节点或者没有节点的节点他们的孩子,交给节点的父节点来看管就行

if (cur->_left == nullptr)
{if (parent == nullptr){_root = cur->_right;}else {if (parent->_left == cur){parent->_left = cur->_right;}else {parent->_right = cur->_right;}}delete cur;return true;
}
else if (cur->_right == nullptr)
{if (parent == nullptr){_root = cur->_left;}else {if (parent->_left == cur){parent->_left = cur->_left;}else {parent->_right = cur->_left;}}delete cur;return true;
}

删除两个子节点的节点

首先要找到右子树最小的节点与要删除的节点进行交换。

这里我们定义一个cur就是要删除的节点,和rightMin右子树最小的节点,和rightMinP右子树最小的节点的父节点。

 

					Node* rightMinP = cur;Node* rightMin = cur->_right;while (rightMin->_left){rightMinP = rightMin;rightMin = rightMin->_left;}cur->_key = rightMin->_key;if (rightMinP->_left == rightMin)rightMinP->_left = rightMin->_right;elserightMinP->_right = rightMin->_right;delete rightMin;return true;

 删除二叉树总代码实现

bool Erase(int 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{// 删除//0-1个孩子的情况if (cur->_left == nullptr){if (parent == nullptr){_root = cur->_right;}else {if (parent->_left == cur){parent->_left = cur->_right;}else {parent->_right = cur->_right;}}delete cur;return true;}else if (cur->_right == nullptr){if (parent == nullptr){_root = cur->_left;}else {if (parent->_left == cur){parent->_left = cur->_left;}else {parent->_right = cur->_left;}}delete cur;return true;}else {// 2 个孩子// 右子树的最大节点作为替代节点Node* rightMinP = cur;Node* rightMin = cur->_right;while (rightMin->_left){rightMinP = rightMin;rightMin = rightMin->_left;}cur->_key = rightMin->_key;if (rightMinP->_left == rightMin)rightMinP->_left = rightMin->_right;elserightMinP->_right = rightMin->_right;delete rightMin;return true;}}}return false;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com