二叉搜索树(BinarySearchTree)
所有左子树的值都小于根,所有右子树的值都大于根
用处:在内存中查找
最多查找高度次
如果能做到满二叉树或完全二叉树,在中国14亿人中找到心动的人只需要31次,10亿是30次(2的三十次方)
查找的话:需要后期的平衡二叉树,和AVL树
搜索二叉树中序遍历时一定程度上是有序的,所以又被叫做排序二叉树
比较数据的大小,我们在声明模板的时候一般申请成key - --class K
Insert操作
先序遍历可以排序+去重
查找Find也很简单
删除操作
#pragma once #include#include using namespace std; //二叉树以后,模板参数用K(key) template struct BSTreeNode { BSTreeNode * left; BSTreeNode * right; K _val; BSTreeNode(const K& val) :left(nullptr) ,right(nullptr) ,_val(val) {} }; template class BSTree { typedef BSTreeNode Node; public: BSTree() :_root(nullptr) {} bool Insert(const K& val) { if (_root == nullptr) { _root = new Node(val); return true; } Node* parent = nullptr; Node* cur = _root; while (cur) { if (cur->_val < val) { parent = cur; cur = cur->right; } else if (cur->_val > val) { parent = cur; cur = cur->left; } else { return false;//树中不允许有相同的元素存在 } } //已经找到了位置,开始放结点 //想要链接的话,必须要通过parent //单靠自己所在位置是链接不了的 cur = new Node(val); if (parent->_val < val) { parent->right = cur; } else { parent->left = cur; } return true; } bool Find(const K& val) { Node* cur = _root; while (cur) { if (cur->_val < val) { cur = cur->right; } else if (cur->_val > val) { cur = cur->left; } else { return true; } } return false; } bool Erase(const K& val) { Node* parent = nullptr; Node* cur = _root; //开始找需要删除的元素 while (cur) { if (cur->_val < val) { parent = cur; cur = cur->right; } else if (cur->_val > val) { parent = cur; cur = cur->left; } else { //找到了以后分三种情况 //1 .该结点没有孩子 2 .该节点没有孩子 3.该节点有两个孩子 //前两种情况可以直接删除,最后一种情况可以用替换法删除 //将左子树的最右结点(也就是最大结点)或者右子树的最小节点(最左)交换删除 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; } 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; } else { //该结点既有左孩子又有右孩子,那么我们找左树的最大或者右树的最小 //在这里我们找右树的最小(也就是最左子树) Node* minParent = cur; Node* min = cur->right; //找小 while (min->left) { minParent = min; min = min->left; } cur->_val = min->_val; if (minParent->left == min) { minParent->left = min->right; } else { minParent->right = cur->right; } delete min; } return true; } } //没有找到 return false; } //递归写法写一个中序遍历 // 中序遍历就是排升序 //写一个_InOrder进行辅助递归 void InOrder() { _InOrder(_root); } void _InOrder(Node* root) { if (root == nullptr) { return; } _InOrder(root->left); cout << root->_val << " "; _InOrder(root->right); } bool InsertR(const K& key) { return _InsertR(_root, key); } Node* FindR(Node* root, const K& key) { return _FindR(root, key); } bool EraseR(Node* root, const K& key) { _EraseR(root, key); } private: bool _EraseR(Node* root, const K& key) { if (root == nullptr) { return false; } if (root->_val < key) { return _EraseR(root->right, key); } else if (root->_val > 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) { min = min->left; } swap(min->_val, del->_key); _EraseR(root->right, key); } delete del; } } Node* _FindR(Node* root, const K& key) { if (root == nullptr) { return root; } if (root->_val < key) { return _FindR(root->right, key); } else if (root->_val > key) { return _FindR(root->left, key); } else { return root; } } bool _InsertR(Node*& root,const K& key) { if (root == nullptr) { root = new Node(key); return true; } if (root->_val < key) { return _InsertR(root->right, key); } else if (root->_val > key) { return _InsertR(root->left, key); } else { return false; } } Node* _root; }; void TestBSTree() { BSTree t; int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9,5,5 }; for (auto e : a) { t.Insert(e); } t.InOrder(); printf("n"); t.Erase(5); t.InOrder(); }



