zoukankan      html  css  js  c++  java
  • 树-二叉查找树

    二叉查找树,二叉搜索树,Binary Search Tree

    二叉查找树性质:左孩子<双亲<右孩子

    若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

    任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

    任意节点的左、右子树也分别为二叉查找树。

    没有键值相等的节点(no duplicate nodes)。

    二叉查找树插入与删除

    插入

    1.若当前的二叉查找树为空,则插入的元素为根节点;

    2.若插入的元素值小于根节点值,则将元素插入到左子树中;

    3.若插入的元素值不小于根节点值,则将元素插入到右子树中。

    删除

    分三种情况进行处理:

    1.p为叶子节点。

    直接删除该节点,再修改其父节点的指针(注意分是根节点和不是根节点)。

    2.p为单支节点(即只有左子树或右子树)。

    让p的子树与p的父亲节点相连,删除p即可(注意分是根节点和不是根节点)。

    3.p的左子树和右子树均不空。

    (找后继,次大值):找到p的后继y,因为y一定没有左子树,所以可以删除y,并让y的父亲节点成为y的右子树的父亲节点,并用y的值代替p的值;

    二叉查找树实现

    //BSTree.h
    #ifndef BSTREE_HXX
    #define BSTREE_HXX

    #include <iostream>
    using namespace std;

    template <class T>
    class BSTNode
    {
        public:
            T key;
            BSTNode *leftchild;
            BSTNode *rigthchild;
            BSTNode *parent;

            BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):
                    key(value),parent(),leftchild(l),right(r){}
    };

    template <class T>
    class BSTree
    {
        private:
            BSTNode<T> *root;
        public:
            BSTree();
            ~BSTree();
           
            void preOrder();//先序遍历
            void inOrder()://中序遍历
            void postOrder();//后序遍历
           
            BSTNode<T> * search(BSTNode<T> *tree,T key);//递归查找
            BSTNode<T> * iterativeSearch(T key);//非递归查找
           
            T minimum();//查找最小结点
            T maximum();//查找最大结点
           
            BSTNode<T> * successor(BSTNode<T> *x);//查找x的后继结点
            BSTNode<T> * predecessor(BSTNode<T> *x);//查找x的前驱结点
           
            void insert(T key);//插入
            void remove(T key);//删除
            void destroy();//销毁二叉树   
    }
    #endif //BSTREE_HXX

    //BSTree.cpp
    #include "BSTree.h"
    #include <iostream>
    using namespace std;

    template <class T>
    BSTree<T>::BSTree():root(NULL)
    {
       
    }

    template <class T>
    BSTree<T>::~BSTree()
    {
        destroy();
    }

    template <class T>
    void BSTree<T>::preOrder()
    {
        BSTNode<T> * tree = root;
        if(tree != NULL)
        {
            cout<<tree->key<<" ";
            preOrder(tree->leftchild);
            preOrder(tree0>rightchild);
        }
    }

    template <class T>
    void BSTree<T>::inOrder()
    {
        BSTNode<T> * tree = root;
        if(tree != NULL)
        {
            inOrder(tree->leftchild);
            cout<<tree->key<<" ";
            inOrder(tree0>rightchild);
        }
    }

    template <class T>
    void BSTree<T>::postOrder()
    {
        BSTNode<T> * tree = root;
        if(tree != NULL)
        {
            postOrder(tree->leftchild);
            postOrder(tree0>rightchild);
            cout<<tree->key<<" ";
        }
    }

    template <class T>
    BSTNode<T> * BSTree<T>::search(BSTNode<T> *tree,T key)
    {
        tree = root;
        if(tree == NULL || tree->key == key)
            return tree;
        if(key < tree->key)
            return search(tree->leftchild,key);
        if(key > tree->key)
            return search(tree->rightchild,key);
    }

    template <class T>
    BSTNode<T> * BSTree<T>::iterativeSearch(T key)
    {
        BSTNode<T> * tree = root;
        while((tree != NULL) && (tree->key != key))
        {
            if(key < tree->key)
                tree = tree->leftchild;
            else
                tree = tree->rightchild;
        }
        return tree;
    }

    template <class T>
    T BSTree<T>::minimum()
    {
        BSTNode<T> * tree = root;
        if(tree == NULL)
            return NULL;
        while(tree->leftchild != NULL)
            tree = tree->leftchild;
        return tree->key;
    }

    template <class T>
    T BSTree<T>::maximum()
    {
        BSTNode<T> * tree = root;
        if(tree == NULL)
            return NULL;
        while(tree->rightchild != NULL)
            tree = tree->rightchild;
        return tree->key;
    }

    //后继结点,次小结点
    template <class T>
    BSTNode<T> * BSTree<T>::successor(BSTNode<T> *x)
    {
        // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
        if(x->rightchild != NULL)
            return minimum(x->rightchild);
        // 如果x没有右孩子。则x有以下两种可能:
        // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
        // (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结
        BSTNode<T> * p = x->parent;
        while((p != NULL) && (x == p->rightchild))
        {
            x = p;
            p = p->parent;
        }
        return p;
    }

    //前驱结点,次大结点
    template <class T>
    BSTNode<T> * BSTree<T>::predecessor(BSTNode<T> *x)
    {
       
        if(x->leftchild != NULL)
            return minimum(x->leftchild);
           
        BSTNode<T> * p = x->parent;
        while((p != NULL) && (x == p->leftchild))
        {
            x = p;
            p = p->parent;
        }
        return p;
    }

    template <class T>
    void BSTree<T>::insert(T key)
    {
        BSTNode<T> * p = NULL;
        BSTNode<T> * x = root;
        while(x!=NULL)
        {
            p = x;
            if(key < x->key)
                x = x->leftchild;
            else
                x = x->rightchild;
        }
        BSTNode<T> * newNode = new BSTNode<T>;
        newNode->key = key;
        newNode->parent = p;
        if(p == NULL)
            root = newNode;
        elseif(newNode->key < p->key)
            p->leftchild = newNode;
        else
            p->rightchild = newNode;
    }

    template <class T>
    void BSTree<T>::remove(T key)
    {
        BSTNode<T> * x = NULL;
        BSTNode<T> * y = NULL;
        BSTNode<T> * tree = root;
       
        BSTNode<T> * removeNode = search(root,key);
       
        if((removeNode->leftchild == NULL) || (removeNode->rightchild == NULL))
            y = removeNode;
        else
            y = successor(removeNode);
       
        if(y->leftchild != NULL)
            x = y->leftchild;
        else
            x = y->rightchild;
           
        if(x != NULL)
            x->parent = y->parent;
           
        if(y->parent == NULL)
            tree = x;
        elseif(y == y->parent->leftchild)
            y->parent->leftchild = x;
        else
            y->parent->rightchild = x;
           
        if(y != removeNode)
            removeNode->key = y->key;
        delete y;
    }

    template <class T>
    void BSTree<T>::destroy(BSTNode<T> * tree)
    {
        tree = root;
        if(tree == NULL)
            return;
        if(tree->leftchild != NULL)
            return destroy(tree->leftchild);
        if(tree->rightchild != NULL)
            return destroy(tree->rightchild);
       
        delete tree;
        tree = NULL;
    }

  • 相关阅读:
    百度网盘提交提取密码:根据cookies获取loginId 的js
    javaScript 中的私有,共有,特权属性和方法
    centos7 设置时区和时间
    centos 7 su jenkins 切换不过去
    在宿主机查看docker使用cpu、内存、网络、io情况
    Centos6.8通过yum安装mysql5.7 centos7.5适用
    docker-compose 安装redis sentinel,共享主机网络模式
    spring boot通过Interceptor和HandlerMethodReturnValueHandler实现统一处理为controller返回对象统计处理时间
    centos 7.5安装docker-CE 18
    centos查看系统版本信息
  • 原文地址:https://www.cnblogs.com/lucas-hsueh/p/3730503.html
Copyright © 2011-2022 走看看