ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
二叉搜索树或是一颗空二叉树, 或是具有以下性质的二叉树: 1.若左子树不为空, 则左子树上所有结点的关键字值均小于根结点的关键字值. 2.若右子树不为空, 则右子树上所有结点的关键字值均大于根结点的关键字值. 3.左右子树也分别是二叉搜索树. 性质: 若以中序遍历一颗二叉搜索树, 将得到一个以关键字值递增排列的有序序列. 1.搜索实现: 若二叉树为空, 则搜索失败. 否则, 将x与根结点比较. 若x小于该结点的值, 则以同样的方法搜索左子树, 不必搜索右子树. 若x大于该结点的值, 则以同样的方法搜索右子树, 而不必搜索左子树. 若x等于该结点的值, 则搜索成功终止. search()为递归搜索, search1()为迭代搜索. 2.插入实现: 插入一个新元素时, 需要先搜索新元素的插入位置. 如果树种有重复元素, 返回Duplicate. 搜索达到空子树, 则表明树中不包含重复元素. 此时构造一个新结点p存放新元素x, 连至结点q, 成为q的孩子, 则新结点p成为新二叉树的根. 3.删除实现: 删除一个元素时, 先搜索被删除结点p, 并记录p的双亲结点q. 若不存在被删除的元素, 返回NotPresent.  (1)若p有两颗非空子树, 则搜索结点p的中序遍历次序下的直接后继结点, 设为s. 将s的值复制到p中.  (2)若p只有一颗非空子树或p是叶子, 以结点p的唯一孩子c或空子树c = NULL取代p. (3)若p为根结点, 删除后结点c成为新的根. 否则若p是其双亲确定左孩子, 则结点c也应成为q的左孩子, 最后释放结点p所占用的空间. 实现代码: ~~~ #include "iostream" #include "cstdio" #include "cstring" #include "algorithm" #include "cmath" #include "utility" #include "map" #include "set" #include "vector" using namespace std; typedef long long ll; const int MOD = 1e9 + 7; enum ResultCode{ Underflow, Overflow, Success, Duplicate, NotPresent }; // 赋值为0, 1, 2, 3, 4, 5 template <class T> class DynamicSet { public: virtual ~DynamicSet() {} virtual ResultCode Search(T &x) const = 0; virtual ResultCode Insert(T &x) = 0; virtual ResultCode Remove(T &x) = 0; /* data */ }; template <class T> struct BTNode { BTNode() { lChild = rChild = NULL; } BTNode(const T &x) { element = x; lChild = rChild = NULL; } BTNode(const T &x, BTNode<T> *l, BTNode<T> *r) { element = x; lChild = l; rChild = r; } T element; BTNode<T> *lChild, *rChild; /* data */ }; template <class T> class BSTree : public DynamicSet<T> { public: explicit BSTree() { root = NULL; } // 只可显示转换 virtual ~BSTree() { Clear(root); } ResultCode Search(T &x) const; ResultCode Search1(T &x) const; ResultCode Insert(T &x); ResultCode Remove(T &x); protected: BTNode<T> *root; private: void Clear(BTNode<T> *t); ResultCode Search(BTNode<T> *p, T &x) const; /* data */ }; template <class T> void BSTree<T>::Clear(BTNode<T> *t) { if(t) { Clear(t -> lChild); Clear(t -> rChild); cout << "delete" << t -> element << "..." << endl; delete t; } } template< class T> ResultCode BSTree<T>::Search(T &x) const { return Search(root, x); } template <class T> ResultCode BSTree<T>::Search(BTNode<T> *p, T &x) const { if(!p) return NotPresent; if(x < p -> element) return Search(p -> lChild, x); if(x > p -> element) return Search(p -> rChild, x); x = p -> element; return Success; } template <class T> ResultCode BSTree<T>::Search1(T &x) const { BTNode<T> *p = root; while(p) { if(x < p -> element) p = p -> lChild; else if(x > p -> element) p = p -> rChild; else { x = p -> element; return Success; } } return NotPresent; } template <class T> ResultCode BSTree<T>::Insert(T &x) { BTNode<T> *p = root, *q = NULL; while(p) { q = p; if(x < p -> element) p = p -> lChild; else if(x > p -> element) p = p -> rChild; else { x = p -> element; return Duplicate; } } p = new BTNode<T>(x); if(!root) root = p; else if(x < q -> element) q -> lChild = p; else q -> rChild = p; return Success; } template <class T> ResultCode BSTree<T>::Remove(T &x) { BTNode<T> *c, *s, *r, *p = root, *q = NULL; while(p && p -> element != x) { q = p; if(x < p -> element) p = p -> lChild; else p = p -> rChild; } if(!p) return NotPresent; x = p -> element; if(p -> lChild && p -> rChild) { s = p -> rChild; r = p; while(s -> lChild) { r = s; s = s -> lChild; } p -> element = s -> element; p = s; q = r; } if(p -> lChild) c = p -> lChild; else c = p -> rChild; if(p == root) root = c; else if(p == q -> lChild) q -> lChild = c; else q -> rChild = c; delete p; return Success; } int main(int argc, char const *argv[]) { BSTree<int> bst; int x = 28; bst.Insert(x); x = 21; bst.Insert(x); x = 25; bst.Insert(x); x = 36; bst.Insert(x); x = 33; bst.Insert(x); x = 43; bst.Insert(x); return 0; } ~~~