数据结构(九)二叉搜索树
二叉搜索树–c++实现
二叉搜索树的定义
二叉搜索树是一棵二叉树,可能为空;一颗非空的二叉搜索树满足以下特征:
-
每个元素都有一个关键字,并且任意两个元素的关键字都不同;因此,所有的关键字都是唯一的。
-
在根节点的左子树中,元素的关键字都小于根节点的关键字。
-
在根节点的右子树中,元素的关键字都大于根节点的关键字。
而对于二叉搜索树的所有元素都有一个唯一的关键字,这个要求也可以去除,然后将小于等于代替上述的小于,将大于等于代替上述的大于,这样的二叉树称为有重复值的二叉搜索树。
二叉搜索树的描述
在binarySearchTree.h文件中定义了二叉搜索树的节点,声明了二叉搜索树类。
template<class K, class E>
struct binaryTreeNode {
K key;
E value;
binaryTreeNode<K, E> *leftChild, *rightChild;
binaryTreeNode() { leftChild = rightChild = nullptr; }
binaryTreeNode(const K &theKey, const E &theElement) {
key = theKey;
value = theElement;
leftChild = rightChild = nullptr;
}
};
template<class K, class E>
class binarySearchTree {
private:
binaryTreeNode<K, E> *root;
int size;
public:
binarySearchTree();
~binarySearchTree();
void delAll(binaryTreeNode<K,E> *root);
binaryTreeNode<K, E> *find(K &theKey) const;
void insert(const K &theKey, const E &theValue);
void erase(const K &theKey);
int getSize() const;
bool empty() const;
};
二叉搜索树的实现
template<class K, class E>
binarySearchTree<K, E>::binarySearchTree() {
root = new binaryTreeNode<K, E>;
size = 0;
}
template<class K, class E>
binarySearchTree<K, E>::~binarySearchTree() {
delAll(root);
}
template<class K, class E>
binaryTreeNode<K, E> *binarySearchTree<K, E>::find(K &theKey) const {
binaryTreeNode<K, E> *p = root;
while (p != nullptr) {
if (p->key > theKey) {
p = p->leftChild;
} else if (p->key < theKey) {
p = p->rightChild;
} else {
return p;
}
}
}
template<class K, class E>
void binarySearchTree<K, E>::insert(const K &theKey, const E &theValue) {
if (size == 0) {
root->key = theKey;
root->value = theValue;
size++;
return;
}
binaryTreeNode<K, E> *p = root,*pp;
while (p != nullptr) {
pp = p;
if (p->key > theKey) {
p = p->leftChild;
} else p = p->rightChild;
}
if (pp->key > theKey){
pp->leftChild = new binaryTreeNode<K,E>(theKey,theValue);
} else pp->rightChild = new binaryTreeNode<K,E>(theKey,theValue);
size++;
}
template<class K, class E>
void binarySearchTree<K, E>::erase(const K &theKey) {
binaryTreeNode<K, E> *p = root;
binaryTreeNode<K, E> *pp = nullptr;
while (p != nullptr) {
if (p->key == theKey) break;
pp = p;
if (p->key > theKey) p = p->leftChild;
else p = p->rightChild;
}
if (p->leftChild != nullptr && p->rightChild != nullptr) {//两个孩子
binaryTreeNode<K, E> *s = p->leftChild;
binaryTreeNode<K, E> *ps = p;
while (s->rightChild != nullptr) {
ps = s;
s = s->rightChild;
}
K k = s->key;
E v = s->value;
erase(k);
p->key = k;
p->value = v;
ps->rightChild = nullptr;
size--;
return;
} else{
binaryTreeNode<K,E> *c ;
if(p->leftChild != nullptr)
c = p->leftChild;
else
c = p->rightChild;
if(p == root) root =c;
else{
if(p == pp->leftChild) pp->leftChild = c;
else pp->rightChild = c;
size--;
delete p;
}
}
}
template<class K, class E>
int binarySearchTree<K, E>::getSize() const {
return size;
}
template<class K, class E>
bool binarySearchTree<K, E>::empty() const {
return size ==0;
}
template<class K, class E>
void binarySearchTree<K, E>::delAll(binaryTreeNode<K, E> *root) {
if (root == nullptr) return;
else{
delAll(root->leftChild);
delAll(root->rightChild);
delete root;
}
}
测试程序:
#include <iostream>
using namespace std;
int main(){
binarySearchTree<int, int> binarySearchTree;
binarySearchTree.insert(12,12);
binarySearchTree.insert(23,23);
binarySearchTree.insert(56,56);
binarySearchTree.insert(42,42);
binarySearchTree.insert(9,9);
binarySearchTree.insert(34,34);
cout << "size = " << binarySearchTree.getSize()<<endl;
binarySearchTree.erase(23);
cout << "after erase, size = " << binarySearchTree.getSize() <<endl;
return 0;
}
测试结果:
size = 6
after erase, size = 5