BTS--Binary Search Tree 二叉查找树

Binary Search Tree

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉查找树。

性质

    二叉查找树是一个带根的二叉树,内部每个结点都储存一个键,并且都有两个不同的子树。对于树中的每个结点X,他左子树中的所有项都小于X中的项,右子树中所有项的值都大于X中的项。

   如图所示为二叉查找树:

树的实现

    二叉查找树一般包含如下insert,delete,findMax,findMin,contain等功能,通常递归地编写这些操作。

结点的构造

    一个结点包含一个键以及指向左右子树的指针:

template <typename Object>struct BinaryNode{
    Object element;
    BinaryNode<Object> *left;
    BinaryNode<Object> *right;
    BinaryNode(const Object& theElement,BinaryNode<Object> *Left,BinaryNode<Object> *Right):
            element(theElement),left(Left),right(Right){}
};

插入操作

    递归地进行操作,插入后要符合树的定义,即该结点的值比左子树上所有结点大,比右子树上所有结点小。

    如果当前结点为空,直接插入;如果当前结点所含项的值比将要插入的结点大,因为要保证右边的一定大于结点,左边的一定小于结点,则应向当前结点的左子树插入,(如果向右子树插入,会造成右子树中有元素小于当前结点,不符合定义);如果当前结点所含项的值比将要插入的结点小,同理,则应向当前结点的右子树插入。

template <typename Object>void BinarySearchTree<Object>::insert(const Object &obj, BinaryNode<Object> *&t) {
    if(t==NULL)t=new BinaryNode<Object>(obj,NULL,NULL);
    else if(obj<t->element) insert(obj,t->left);
    else insert(obj,t->right);
}

查找操作

    从根节点遍历,如果当前结点所含项的值等于被查找元素,则找到;如果小于被查找元素,则继续对其左子树遍历;若大于被查找元素,对其右子树遍历。

template <typename Object>bool BinarySearchTree<Object>::contains(const Object &obj, BinaryNode<Object> *t) {
    if(t==NULL)return false;
    else if(obj<t->element) return contains(obj,t->left);
    else if(t->element<obj) return contains(obj,t->right);
    else return true;
}

查找最大、最小操作

   由树的性质可知,树上的最小元素一定在左结点,最大的元素一定在右结点。直接递归求解即可

template <typename Object>BinaryNode<Object>* BinarySearchTree<Object>::findMax(BinaryNode<Object> *t)  {
    if(t==NULL) return NULL;
    if(t->right==NULL) return t;
    return findMax(t->right);
}
template <typename Object>BinaryNode<Object>* BinarySearchTree<Object>::findMin(BinaryNode<Object> *t){
    if(t==NULL) return NULL;
    if(t->left==NULL) return t;
    return findMin(t->left);
}

删除操作

    如果被删除的结点是一片树叶,则直接删除即可。如果该结点有一个儿子,则该结点可以在其父亲节点调整它的链以绕过该节点后被删除。复杂的情况是处理具有两个儿子的结点,我们一般的删除策略是用其右子树的最小结点代替该结点,再递归删除那个结点。

template <typename Object>void BinarySearchTree<Object>::remove(const Object &obj, BinaryNode<Object> *&t) {
    if(t==NULL) return;
    else if(obj<t->element) remove(obj,t->left);
    else if(t->element<obj) remove(obj,t->right);
    else if(t->right==NULL||t->left==NULL){
        BinaryNode<Object>*tmp=t;
        t=(t->left!=NULL)?t->left:t->right;
        delete tmp;
    }
    else{
        t->element=findMin(t->right)->element;
        remove(t->element,t->right);
    }
}

完整代码

template <typename Object>struct BinaryNode{
    Object element;
    BinaryNode<Object> *left;
    BinaryNode<Object> *right;
    BinaryNode(const Object& theElement,BinaryNode<Object> *Left,BinaryNode<Object> *Right):
            element(theElement),left(Left),right(Right){}
};
template <typename Object>class BinarySearchTree{
private:
    BinaryNode<Object> *root;
public:
    BinarySearchTree();
    BinarySearchTree(const BinarySearchTree<Object>&);
    ~BinarySearchTree();
    const Object& findMin();
    const Object& findMax();
    bool contains(const Object&);
    bool empty()const;
    void printTree();
    void clear();
    void insert(const Object&);
    void remove(const Object&);
    const BinarySearchTree<Object>&operator=(const BinarySearchTree<Object>&);
private:
    void insert(const Object&,BinaryNode<Object>* &);
    void remove(const Object&,BinaryNode<Object>* &);
    BinaryNode<Object>* findMin(BinaryNode<Object>*);
    BinaryNode<Object>* findMax(BinaryNode<Object>*);
    bool contains(const Object&,BinaryNode<Object>*);
    void clear(BinaryNode<Object>*&);
    void printTree(BinaryNode<Object>*);
    BinaryNode<Object>*clone(BinaryNode<Object> *t)const;
};
template <typename Object>void BinarySearchTree<Object>::insert(const Object &obj, BinaryNode<Object> *&t) {
    if(t==NULL)t=new BinaryNode<Object>(obj,NULL,NULL);
    else if(obj<t->element) insert(obj,t->left);
    else insert(obj,t->right);
}
template <typename Object>bool BinarySearchTree<Object>::contains(const Object &obj, BinaryNode<Object> *t) {
    if(t==NULL)return false;
    else if(obj<t->element) return contains(obj,t->left);
    else if(t->element<obj) return contains(obj,t->right);
    else return true;
}
template <typename Object>BinaryNode<Object>* BinarySearchTree<Object>::findMax(BinaryNode<Object> *t)  {
    if(t==NULL) return NULL;
    if(t->right==NULL) return t;
    return findMax(t->right);
}
template <typename Object>BinaryNode<Object>* BinarySearchTree<Object>::findMin(BinaryNode<Object> *t){
    if(t==NULL) return NULL;
    if(t->left==NULL) return t;
    return findMin(t->left);
}
template <typename Object>void BinarySearchTree<Object>::remove(const Object &obj, BinaryNode<Object> *&t) {
    if(t==NULL) return;
    else if(obj<t->element) remove(obj,t->left);
    else if(t->element<obj) remove(obj,t->right);
    else if(t->right==NULL||t->left==NULL){
        BinaryNode<Object>*tmp=t;
        t=(t->left!=NULL)?t->left:t->right;
        delete tmp;
    }
    else{
        t->element=findMin(t->right)->element;
        remove(t->element,t->right);
    }
}
template <typename Object>void BinarySearchTree<Object>::clear(BinaryNode<Object>*&t) {
    if(t!=NULL){
        clear(t->left);
        clear(t->right);
        delete t;
    }
    t=NULL;
}
template <typename Object>BinaryNode<Object>* BinarySearchTree<Object>::clone(BinaryNode<Object> *t) const {
    if(t==NULL) return NULL;
    return new BinaryNode<Object>(t->element,clone(t->left),clone(t->right));
}
template <typename Object>const BinarySearchTree<Object>& BinarySearchTree<Object>::operator=(
        const BinarySearchTree<Object> &t) {
    if(this!=&t){
        clear();
        root=clone(t.root);
    }
    return *this;
}
template <typename Object>void BinarySearchTree<Object>::printTree(BinaryNode<Object> *t) {
    if(t){
        printTree(t->left);
        std::cout<<t->element<<"  ";
        printTree(t->right);
    }
}
template <typename Object>void BinarySearchTree<Object>::remove(const Object &obj) {
    remove(obj,root);
}
template <typename Object>bool BinarySearchTree<Object>::contains(const Object &obj) {
    return contains(obj,root);
}
template <typename Object>const Object& BinarySearchTree<Object>::findMax(){
    return findMax(root)->element;
}
template <typename Object>const Object& BinarySearchTree<Object>::findMin(){
    return findMin(root)->element;
}
template <typename Object>bool BinarySearchTree<Object>::empty() const {
    return root==NULL;
}
template <typename Object>void BinarySearchTree<Object>::clear() {
    clear(root);
}
template <typename Object>void BinarySearchTree<Object>::insert(const Object &obj) {
    insert(obj,root);
}
template <typename Object>BinarySearchTree<Object>::~BinarySearchTree() {
    clear();
}
template <typename Object>BinarySearchTree<Object>::BinarySearchTree():root(NULL) {}
template <typename Object>BinarySearchTree<Object>::BinarySearchTree(const BinarySearchTree<Object> &obj):root(NULL) {
    root=clone(obj.root);
}
template <typename Object>void BinarySearchTree<Object>::printTree() {
    printTree(root);
}
发布了18 篇原创文章 · 获赞 15 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Juicewyh/article/details/83785597