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

上一篇: 励志日志

下一篇: 考研励志语句

相关内容

热门资讯

女娲传说之灵珠经典台词 女娲传说之灵珠经典台词15句  你们根本不懂爱,你们的爱太过自私,不择手段。——仙乐  你放心,我不...
青春演讲比赛主持词 青春演讲比赛主持词  主持:  男——李勇  女——张雨  女:我与祖国共奋进男:我为崛起献青春。 ...
年会赞助商致辞 年会赞助商致辞(精选5篇)  在日常的学习、工作、生活中,要用到致辞的情况还是蛮多的,致辞具有很强的...
培训会主持词 培训会主持词(精选10篇)  在日常中,大家总免不了要培训及会议吧,那么你知道主持词怎么写吗?下面是...
电影《三少爷的剑》经典台词 电影《三少爷的剑》经典台词精选  1. 冷风如刀,大地荒漠,苍天无情。  2. 这世上永远有两种人,...
《十六个夏天》的经典台词 《十六个夏天》的经典台词大全  1.就说我不是他的收藏品,乱说什么啊!  2.说话冲的人,心里都是软...
80岁生日宴会致辞 80岁生日宴会致辞(精选11篇)  在学习、工作或生活中,大家都不可避免地会接触到致辞吧,致辞具有有...
婚宴长辈证婚人致辞 婚宴长辈证婚人致辞  在平日的学习、工作和生活里,大家总少不了要接触或使用致辞吧,致辞受场合、事件的...
元旦舞会主持词 元旦舞会主持词(精选7篇)  主持词要尽量增加文化内涵、寓教于乐,不断提高观众的文化知识和素养。在人...
圣诞联欢会主持词 圣诞联欢会主持词  活动对象的不同,主持词的写作风格也会大不一样。时代不断在进步,主持成为很多活动不...
美好童年—庆“六一”大型活动... 美好童年—庆“六一”大型活动主持词  利用在中国拥有几千年文化的诗词能够有效提高主持词的感染力。随着...
毕业晚会主持词串词 毕业晚会主持词串词  毕业,是人生的一个转折点,愿你们能展开双翼,飞得更高、看得更远。下面是小编给大...
运动会致辞 运动会致辞(精选5篇)  无论在学习、工作或是生活中,大家或多或少都用到过致辞吧,致辞要求风格的雅、...
六一儿童节的主持稿 六一儿童节的主持稿(精选8篇)  随着社会一步步向前发展,我们都不可避免地要接触到主持稿,主持稿是主...
元旦文艺汇演主持稿 元旦文艺汇演主持稿范文(通用5篇)  在当下社会,很多情况下我们需要用到主持稿,主持稿起到承上启下的...
颁奖主持词 颁奖主持词三篇  主持人在一场活动中是十分重要的,一个好的主持人是一直带动着活动过程中的气氛,让大家...
婚宴答谢宴简短主持词 婚宴答谢宴简短主持词  主持词要根据活动对象的不同去设置不同的主持词。在人们积极参与各种活动的今天,...
汽车公司庆典主持词 汽车公司庆典主持词  利用在中国拥有几千年文化的诗词能够有效提高主持词的感染力。现今社会在不断向前发...
古筝音乐会主持词 古筝音乐会主持词6篇  主持词要把握好吸引观众、导入主题、创设情境等环节以吸引观众。在一步步向前发展...
小学元旦联欢会主持词开场白和... 小学元旦联欢会主持词开场白和结束词  根据活动对象的不同,需要设置不同的主持词。随着社会一步步向前发...