二叉搜索树最重要的性质就是:左< 中 <右。普通的二叉搜索树是没有保证高度平衡的。
1.二叉树的节点构造
template<class K> struct BSTreeNode { K _key; BSTreeNode<K>* _left; BSTreeNode<K>* _right; BSTreeNode(K key) { _key = key; _left = nullptr; _right = nullptr; } }; template<class K> class BsTree { public: typedef BSTreeNode<K> Node; BsTree() :_root(nullptr) {} private: Node* _root }
二叉树的插入
bool Insert(const K& key) { if (!_root)//插入时先判断二叉树是否为空,如果为空先构造根节点 { Node* newnode = new Node(key); _root=newnode; return true; } Node* pre = nullptr;//插入过程中我们应该记录要插入位置的父亲节点 Node* cur = _root;//向下寻找接近key大小的叶子节点 while (cur) { if (cur->_key == key) return false;//如果找到与key相等的值表示树中已存在此节点直接返回 else if (cur->_key < key) { pre = cur; cur = cur->_right; } else { pre = cur; cur = cur->_left; } } if (pre->_key > key)//判断新节点是右子树还是左子树 { Node* newnode = new Node(key); pre->_left = newnode; } else { Node* newnode = new Node(key); pre->_right = newnode; } 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 { //如果要删除节点的子树有一侧为空直接将另一侧的子树换上来 if (cur->_left == nullptr) { if (parent == nullptr)//如果parent是空就表示要删除根节点 _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 { //如果两侧都不为空就找左子树最大的节点或右子树最小的节点与cur进行替换 Node* minParent = cur; Node* min = cur->_right; while (min->_left) { minParent = min; min = min->_left; } cur->_key = min->_key; //替换后直接删除子树的叶子节点即可 if (minParent->_left == min) minParent->_left = min->_right; else minParent->_right = min->_right; delete min; } return true; } } return false; }
搜索树的查找与插入的前半部分基本一致。上面的是迭代版本,下面来看一下递归版本。
递归实现插入和删除
需要注意的是:
在传值的时候采用的是引用传值,可以直接表示父节点的左子树或右子树,不用记录父节点进行链接。
bool _InsertR(Node*& root, const K& key) { if (root == nullptr) { root = new Node(key); return true; } if (root->_key == key) return false; else if (root->_key < key) _InsertR(root->_right, key); else _InsertR(root->_left, 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(min->_key, root->_key); // 递归到右子树去删除 _EraseR(root->_right, key); } delete del; return true; } }