<C++>手撕搜索二叉树
创始人
2024-03-05 06:40:13
0

目录

一、搜索二叉树的性质

二、搜索二叉树的结构定义

三、手撕搜索二叉树非递归

1)Insert()

2)Find()

3)Erase()

4)InOder()

5)BSTree(const BSTree& t) 拷贝构造

6)~BSTree()析构函数

四、手撕搜索二叉树递归

1)InsertR()

2)FindR()

3)EraseR()

五、搜索二叉树完整代码


一、搜索二叉树的性质

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

二、搜索二叉树的结构定义

搜索二叉树主要实现的是K或K/Value模型,这里我们使用K模型来定义,即可以用O(N)的时间复杂度来进行K值的搜索。

 

使用模板来定义

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

三、手撕搜索二叉树非递归

1)Insert()

插入有两种情况:

  • _root == nullptr 根节点等于空

直接new a Node插入即可

if (_root == nullptr)
{_root = new Node(key);return true;
}
  • _root != nullptr 根节点不等于空

我们需要找到适合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{return false;}}//开始插入cur = new Node(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}

 

 

 

2)Find()

直接通过搜索二叉树的性质就可以进行查找,当key值大于cur->_key的值时,就查找cur的右子树,key值小于cur->_key的值时,就查找cur的左子树,直到找到,或者找不到cur == nullptr结束,即逻辑和Inser中的逻辑大同小异;

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

3)Erase()

删除分三种情况:

  • 删除节点没有孩子
  • 删除节点有一个孩子
  1. 有一个左孩子
  2. 有一个右孩子
  • 删除节点有两个孩子

前面两种代码可以合并处理

	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{//开始删除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;cur = nullptr;}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;cur = nullptr;}else{Node* minParent = cur;Node* min = cur->_right;while (min->_left){minParent = min;min = min->_left;}swap(cur->_key, min->_key);if (minParent->_left == min){minParent->_left = min->_right;}else{minParent->_right = min->_right;}delete min;min = nullptr;}return true;}}return false;}

4)InOder()

使用二叉树的中序遍历--midorder traverse

特点:

中序遍历后的值排列是有序的

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

5)BSTree(const BSTree& t) 拷贝构造

使用前序遍历构造

BSTree(const BSTree& t){_Copy(t._root);}Node* _Copy(Node* root) // 使用前序遍历构造{if (root == nullptr){return;}Node* copyRoot = new Node(root->_key);copyRoot->_left = _Copy(root->_left);copyRoot->_left = _Copy(root->_right);return copyRoot;}

6)~BSTree()析构函数

使用后序销毁

	~BSTree(){_Destory(_root);}void _Destory(Node* root) // 使用后序销毁{if (root == nullptr){return;}_Destory(root->_left);_Destory(root->_right);delete root;root = nullptr;}

四、手撕搜索二叉树递归

1)InsertR()

	bool InertR(const K& key){return _InsertR(_root, key);}bool _InsertR(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (root->_key < key){return _InsertR(root->_right, key);}else if (root->_key > key){return _InsertR(root->_left, key);}else{return false;}}

2)FindR()

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

3)EraseR()

    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){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{//找右数的最左节点Node* min = root->_right;while (min->_left){min = min->_left;}swap(root->_key, min->_key);return _InserR(root->_right, key);}delete del;return true;}}

五、搜索二叉树完整代码

template
struct BSTreeNode
{BSTreeNode* _left;BSTreeNode* _right;K _key;BSTreeNode(const K& key):_left(nullptr),_right(nullptr),_key(key){}
};template
class BSTree
{typedef BSTreeNode Node;
public:bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}else{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;}}}void InOrder(){_InOrder(_root);return;}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;}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{//开始删除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;cur = nullptr;}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;cur = nullptr;}else{Node* minParent = cur;Node* min = cur->_right;while (min->_left){minparnt = min;min = min->_left;}swap(cur->_key, min->_key);if (minParent->_left == min){minParent->_left = min->_right;}else{minParent->_right = min->_right;}delete min;min = nullptr;}return true;}}return false;}BSTree() = default;BSTree(const BSTree& t){_Copy(t._root);}~BSTree(){_Destory(_root);}//bool FindR(const K& key){return _FindR(_root, key);}bool InertR(const K& key){return _InsertR(_root, key);}bool EraseR(const K& key){return _EraseR(_root, key);}private:void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}void _Destory(Node* root){if (root == nullptr){return;}_Destory(root->_left);_Destory(root->_right);delete root;root = nullptr;}Node* _Copy(Node* root){if (root == nullptr){return;}Node* copyRoot = new Node(root->_key);copyRoot->_left = _Copy(root->_left);copyRoot->_left = _Copy(root->_right);return copyRoot;}bool _FindR(Node* root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _FindR(root->_right);}else if (root->_key > key){return _FindR(root->_left);}else{return true;}}bool _InsertR(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (root->_key < key){return _InsertR(root->_right, key);}else if (root->_key > key){return _InsertR(root->_left, key);}else{return false;}}bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{//找右数的最左节点Node* min = root->_right;while (min->_left){min = min->_left;}swap(root->_key, min->_key);return _InserR(root->_right, key);}delete del;return true;}}private:Node* _root = nullptr;
};

上一篇: 励志日志

下一篇: 考研励志语句

相关内容

热门资讯

我生病了小学作文【精简6篇】 我生病了小学作文 篇一我生病了前几天,我不知道怎么了,突然感觉身体不舒服。我感到头晕目眩,喉咙痛得像...
新学期新打算小学作文450字... 新学期新打算篇一:我要努力学习新的学期开始了,我制定了新的打算,那就是要努力学习。我相信只有努力学习...
我学会了西红柿炒鸡蛋小学作文... 我学会了西红柿炒鸡蛋小学作文 篇一我学会了西红柿炒鸡蛋上周,我学会了一道简单又美味的菜——西红柿炒鸡...
花朵的小学作文【最新3篇】 花朵的小学作文 篇一花朵的奇妙世界花朵是大自然的美丽礼物,它们以各种各样的颜色和形状装点着我们的环境...
小学生赏花的作文【通用4篇】 小学生赏花的作文 篇一春天是一个充满美丽花朵的季节,我非常喜欢春天。每当春天来临,我就会和家人一起去...
中秋之夜小学生作文【优选3篇... 中秋之夜小学生作文 篇一中秋之夜,月亮圆圆的,像一块白玉挂在天空中。我和爸爸妈妈一起出门,欣赏美丽的...
油面筋塞肉小学作文(推荐3篇... 油面筋塞肉小学作文 篇一我喜欢吃美食,尤其是一些特色的小吃。最近,我发现了一种非常好吃的小吃,那就是...
学游泳的小学作文(实用3篇) 学游泳的小学作文 篇一学游泳的小学作文大家好!我是小明,今天我要给大家分享一下我学游泳的经历。我是一...
小学生作文老师我想对你说【最... 小学生作文老师我想对你说 篇一尊敬的老师:您好!我是您的学生小明。我想借这篇作文向您表达我的感激之情...
一次有趣的实验小学生作文80... 一次有趣的实验篇一昨天,我参加了一次非常有趣的实验。老师让我们小组一起进行,我非常期待这个实验的结果...
春天小学一年级作文300字【... 春天小学一年级作文300字 篇一我的春天春天来了,大地上百花盛开,绿草如茵。我喜欢春天,因为春天是个...
校园的一角的作文【优选6篇】 校园的一角的作文 篇一校园的一角在校园的一角,有一个小花园,是我最喜欢的地方。虽然它不大,但却别有一...
参观科技馆的小学作文400字... 参观科技馆的小学作文400字 篇一:奇妙的科技世界我参观了我们学校附近的科技馆,这里展示了许多令人惊...
值得的学生作文【实用3篇】 值得的学生作文 篇一突破自我,迈向成功作为一名学生,我们应该时刻保持一种积极向上的心态,勇于追求进步...
走进直播间小学作文(最新4篇... 走进直播间小学作文 篇一近年来,随着互联网技术的快速发展,直播已经成为了一种非常流行的媒体形式。除了...
我的学校小学作文350字【精... 我的学校小学作文350字 篇一我所在的学校是一所小学,位于市区的中心地带。学校占地面积较小,但是设施...
春节大扫除小学作文【精选6篇... 春节大扫除小学作文 篇一:春节大扫除的乐趣春节是中国人最重要的传统节日之一,也是一年中家庭团聚最为频...
抓田螺小学作文(最新5篇) 抓田螺小学作文 篇一我和小伙伴们一起去抓田螺今天,天气晴朗,阳光明媚,我和几个好朋友决定一起去抓田螺...
送别的作文【推荐3篇】 送别的作文 篇一送别的作文 篇一人生中,不论是离别还是告别,都是一种成长的过程。无论是与亲人分离,还...
两个“可怜”作文(最新3篇) 两个“可怜”作文 篇一在生活中,我们常常会遇到一些让人心生怜悯的事情。这些事情或许是因为某些原因而导...