美文网首页
数据结构算法之二分搜索树

数据结构算法之二分搜索树

作者: Peakmain | 来源:发表于2019-04-01 14:25 被阅读0次

定义

根结点的右结点一定比根结点大,左结点一定比根结点小。


image.png

如上图,我们若熟悉树的遍历我们可以从上图看出二叉搜索树的中序遍历就是从小到大排序。

定义结点

template<class K, class V>
struct TreeNode {
public:
    TreeNode(TreeNode<K, V> *pNode) {
        this->left = pNode->left;
        this->right = pNode->right;
        this->key = pNode->key;
        this->value = pNode->value;
    }

    TreeNode<K, V> *left = NULL;
    TreeNode<K, V> *right = NULL;
    K key;
    V value;

    TreeNode(K key, V value) {
        this->right = NULL;
        this->left = NULL;
        this->key = key;
        this->value = value;
    }
};

二分搜索树

首先需要一个根节点和个数

template<class K, class V>
class BST {
    TreeNode<K, V> *root;// 根节点
    int count;// 个数

public:
    BST() {
        root = NULL;
        count = 0;
    }

    ~BST() {

    }
}

判断一个树是否包含

    bool contains(K key) {
        TreeNode<K, V> *node = root;

        while (node) {
            if (node->key == key) {
                return node->value;
            } else if (node->key > key) {
                node = node->left;
            } else {
                node = node->right;
            }
        }

        return false;
    }

首先我们要判断该结点是否为空,若为空,则new一个,然后判断,如果key小于结点的key则放到左边,若大于则放右边,反之相等的时候,直接替换值就可以了。

添加一个树

  void put(K key, V value) {
        root = addNode(root, key, value);
    }
 // 返回一个节点 (
    TreeNode<K, V> *addNode(TreeNode<K, V> *pNode, K key, V value) {
        if (pNode == NULL) {
            count++;
            return new TreeNode<K, V>(key, value);
        }
        //当前的key小于结点的key,添加到左边
        if (key < pNode->key) {
            pNode->left = addNode(pNode->left, key, value);
        } else if (key > pNode->key) {
            pNode->right = addNode(pNode->right, key, value);
        } else {
            pNode->value = value;
        }

        return pNode;
    }

删除结点

删除结点总体分为四种情况
1.删除的结点的左右结点都为空,这种情况直接删除就可以了
2.删除的结点的左结点为空,返回右结点
3.删除的右结点为空,返回左结点
4.删除的结点左右都不为空

    // 删除
    void remove(K key) {
        // 分情况解决
        root = removeNode(root, key);
    }
TreeNode<K, V> *removeNode(TreeNode<K, V> *pNode, K key) {
        if (key < pNode->key) {
            pNode->left = removeNode(pNode->left, key);
        } else if (key > pNode->key) {
            pNode->right = removeNode(pNode->right, key);
        } else {// 相等
            count--;
            if (pNode->left == NULL && pNode->right == NULL) {
                delete pNode;
                return NULL;
            } else if (pNode->left == NULL) {
                TreeNode<K, V> *right = pNode->right;
                delete pNode;
                return right;
            } else if (pNode->right == NULL) {
                TreeNode<K, V> *left = pNode->left;
                delete pNode;
                return left;
            } else {
                // 左右两子树都不为空
               TreeNode<K, V> *successor = new TreeNode<K, V>(maximum(pNode->left));
                successor->left = deleteMax(pNode->left);
                count++;
                successor->right = pNode->right;
                delete (pNode);
                return successor;
            }
        }
        return pNode;
    }
    TreeNode<K, V> *deleteMax(TreeNode<K, V> *pNode) {
        //找到最大值
       if (pNode->right == NULL) {
            TreeNode<K, V> *left = pNode->left;
            delete (pNode);
            count--;
            return left;
        }
        pNode->right = deleteMax(pNode->right);
        return pNode;
    }

    // 查找当前树的最大值
    TreeNode<K, V> *maximum(TreeNode<K, V> *pNode) {
        // 不断的往右边找,直到找到右子树为空节点
        if (pNode->right == NULL) {
            return pNode;
        }
        return maximum(pNode->right);
    }

主要分析最后一种情况,比如上面删除的是2这个结点,我们首先去左边找到它的最大值也就是上面代码中的maximum方法,此时最大值是0这个结点,我们去new一个新节点,值为0(或者去它的右边找到它的最小值)。随后将移除的结点的右结点赋值给新节点的右结点,而将原本0结点的左结点重新赋值给新节点

相关文章

  • 数据结构算法之二分搜索树

    定义 根结点的右结点一定比根结点大,左结点一定比根结点小。 如上图,我们若熟悉树的遍历我们可以从上图看出二叉搜索树...

  • Go语言数据结构和算法-BinarySearchTree(二叉搜

    Go语言数据结构和算法-BinarySearchTree(二叉搜索树) 二叉搜索树的数据结构 Insert(val...

  • day17_选择排序_数组的搜索算法

    选择排序 规律: 数组的搜索算法之二分搜索法

  • 算法草稿

    常用算法集合 字符处理算法数组与查找链表树算法思路 递归、动态规划、BFS/DFS、双指针、二分法搜索数据结构的...

  • 无标题文章

    # 数据结构与算法之二叉树的存储结构 ``` #include typedef char Elemtype; ty...

  • 数据结构之二叉堆、堆排序

    前言 上一篇写了数据结构之二叉搜索树、AVL自平衡树,这次来写堆。 堆的创造者 很久以前排序算法的时间复杂度一直是...

  • 手敲数据结构——使用二分搜索树实现Set

    关于实现二分搜索树,可以看前面的文章 手敲数据结构——二分搜索树

  • 1-3 课程的注意事项

    1.《玩转数据结构》和《算法与数据结构》的区别  后者的主要内容包括三个数据结构(二分搜索树、堆、并查集)、排序算...

  • 数据结构与算法--深度和广度优先搜索

    什么是“搜索”算法? 算法是作用于具体数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于“图”这种数据结构...

  • AVL 树

    一:什么是 AVL 树? 在我的上一篇文章《二分搜索树与二分查找法》中,详细介绍了二分搜索树这种数据结构。二分搜索...

网友评论

      本文标题:数据结构算法之二分搜索树

      本文链接:https://www.haomeiwen.com/subject/gqcvbqtx.html