二叉检索树
- 属性:对于二叉检索树(Binary Search Tree,BST)的任何一个结点,设其值为K,则该结点左子树中任意一个结点的值都小于K;该结点右字数中任意一个结点的值都大于或等于K。
- 特点:按照中序遍历将各结点打印出来,就会得到由小到大排列的结点。
如下图所示: - 在实现BST之前,首先需要对字典进行定义,字典提供在数据库中存储、查询、删除记录的功能。
字典的ADT:
template<typename Key, typename E>class Dictionary{private: void operator =(const Dictionary&){} Dictionary(const Dictionary&){}public: Dictionary(){} virtual ~Dictionary(){} virtual void clear() = 0; virtual void insert(const Key& k, const E& e) = 0; virtual E remove(const Key& k) = 0; virtual E removeAny() = 0; virtual E find(const Key& k) const = 0; virtual int size() = 0;};
template<typename Key, typename E>class BST : public Dictionary < Key, E > {private: BSTNode<Key, E>* root; int nodecount; void clearhelp(BSTNode<Key, E>*); //清除二叉树 BSTNode<Key, E>* inserthelp(BSTNode<Key, E>*, const Key&, const E&); //插入函数 BSTNode<Key, E>* deletemin(BSTNode<Key, E>*); //删除最小结点 BSTNode<Key, E>* getmin(BSTNode<Key, E>*); //获取最小结点的值 BSTNode<Key, E>* removehelp(BSTNode<Key, E>*, const Key&); //移除函数 E findhelp(BSTNode<Key, E>*, const Key&) const; //查找函数 void printhelp(BSTNode<Key, E>*, int) const; //打印函数 public: BST() { root = NULL; nodecount = 0; } //构造函数 ~BST() { clearhelp(root); } //析构函数 //清除二叉树 void clear() { clearhelp(root); root = NULL; nodecount = 0; } //插入函数 void insert(const Key& k,const E& e) { root = inserthelp(root, k, e); nodecount++; } //移除函数 E remove(const Key& k) { E temp = findhelp(root, k); if (temp != NULL) { root = removehelp(root, k); nodecount } return temp; } //移除所有元素 E removeAny() { if (root != NULL) { E temp = root->element; root = removehelp(root, root->key()); nodecount return temp; } else return NULL; } //查找元素 E find(const Key& k) const { return findhelp(root, k); } //返回当前结点的数量 int size() { return nodecount; } //打印二叉树 void print() const { if (root == NULL) cout << "The BST is empty!" << endl; else printhelp(root, 0); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 查找函数:将字数的根结点及检索的值作为参数,使用递归函数实现。
template<typename Key, typename E>E BST<Key, E>::findhelp(BSTNode<Key, E>* root, const Key& k) const{ if (root == NULL) return NULL; if (k < root->key()) return findhelp(root->left(), k); else if (k > root->key()) return findhelp(root->right(), k); else return root->element(); }
- 插入函数:要插入一个值K,首先必须要找到它应该放在书机构的什么地方。这样就会把它带到一个叶结点,或者一个在待插入的方向上没有子结点的分支结点。将这个结点即为R,接着,把一个包含K的结点作为R的子结点加上去。
从根结点到被插入结点的父节点,该路径上的各个结点都被赋予了相应的子结点指针值。
template<typename Key, typename E>BSTNode<Key, E>* BST<Key, E>::inserthelp(BSTNode<Key, E>* root, const Key& k, const E& it){ if (root == NULL) return new BSTNode<Key, E>(k, it, NULL, NULL); if (k < root->key()) root->setLeft(inserthelp(root->left(), k, it)); else root->setRight(inserthelp(root->right(), k, it)); return root; }
- 由于函数调用了deletemin的缘故,在回到根结点路径上的各个结点的左指针都被重新赋予指向子树。
template<typename Key, typename E>BSTNode<Key, E>* BST<Key, E>::deletemin(BSTNode<Key, E>* rt){ if (rt->left() == NULL) { BSTNode<Key, E>* temp = rt->right(); delete rt; return temp->right(); } else{ rt->setLeft(deletemin(rt->left())); return rt; }}
template<typename Key, typename E>BSTNode<Key, E>* BST<Key, E>::getmin(BSTNode<Key, E>* rt){ if (rt->left() == NULL) return rt; else return getmin(rt->left());}
- 如果想把一个有两个子结点的结点值删除,只需要对其右字数调用函数deletemin,并用寒素的返回值替代被删除的值。
template<typename Key, typename E>BSTNode<Key, E>* BST<Key, E>::removehelp(BSTNode<Key, E>* rt, const Key& k){ if (rt == NULL) return NULL; else if (k < rt->key()) rt->setLeft(removehelp(rt->left(), k)); else if (k > rt->key()) rt->setRight(removehelp(rt->right(), k)); else { BSTNode<Key, E>* temp = rt; if (rt->left() == NULL) { rt = rt->right(); delete temp; } else if (rt->right() == NULL) { rt = rt->left(); delete temp; } else { BSTNode<Key, E>* t = getmin(rt->right()); rt->setElement(t->element()); rt->setKey(t->key()); rt->setRight(deletemin(rt->right())); delete temp; } } return rt;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
template<typename Key, typename E>void BST<Key, E>::clearhelp(BSTNode<Key, E>* root){ if (root == NULL) return; clearhelp(root->left()); clearhelp(root->right()); delete root;}
template<typename Key, typename E>void BST<Key, E>::printhelp(BSTNode<Key, E>* root, int level) const{ if (root == NULL) return; printhelp(root->left(), level + 1); for (int i = 0; i < level; i++) cout << " "; cout << root->key() << endl; printhelp(root->right(), level + 1); }