美文网首页
数据结构 - 二叉搜索树

数据结构 - 二叉搜索树

作者: nlpming | 来源:发表于2021-09-23 22:36 被阅读0次

二叉搜索树定义

  • 二叉搜索树首先其是一个二叉树;并且每个结点的键值都大于左孩子,且小于右孩子。以左右孩子为根结点的子树仍为二叉搜索树。 注意:二叉搜索树不一定是完全二叉树。堆肯定是一棵完全二叉树,所以可以用数组表示。
  • 所以对于二叉搜索树。根结点大于左子树所有结点的值,小于右子树所有结点的值。
二叉搜索树示例.png

二叉搜索树优势

  • 二分搜索树常用来实现字典、集合等数据结构,比如STL中的Map,Set类的实现。二分搜索树在查找、删除、插入一个元素的时间复杂度都为O(logn);使用二叉搜索树能够很容易找到:最大值max、最小值min、排序位置rank等操作。
二分搜索树时间复杂度.png

二叉搜索树劣势

  • 如果建立二叉搜索树,输入的是一个排序好的数组。此时二叉搜索树退化成为了链表。所以二叉搜索树应该建成一个平衡二叉树。比如常见的红黑树。

二叉搜索树相关操作

  • 插入元素、删除元素(最难);
  • 查找元素、是否包含元素;
  • 先序、中序、后续遍历二叉搜索树;注意,对于二叉搜索树中序遍历结果是一个递增的序列;
  • max, min, floor, ceil, rank, select等;
#ifndef WORKSPACE_BINARY_SEARCH_TREE_H
#define WORKSPACE_BINARY_SEARCH_TREE_H

#include <iostream>
#include <queue>
#include <cassert>

using namespace std;

/*
 * 二叉搜索树实现;
 * */

template<typename Key, typename Value>
class BST{
private:
    //定义二叉树的一个结点;
    struct Node{
        Key key;
        Value value;
        Node *left;
        Node *right;
        Node(Key key, Value value){
            this->key = key;
            this->value = value;
            this->left = this->right = NULL;
        }

        Node(Node *node){
            this->key = node->key;
            this->value = node->value;
            this->left = node->left;
            this->right = node->right;
        }
    };

    Node *root;
    int count;

private:
    //以node为根的二叉搜索树中,插入结点(key, value)
    Node* insert(Node *node, Key key, Value value){
        if(node == NULL){
            count++;
            return new Node(key, value);
        }

        if(key == node->key)
            node->value = value;
        else if(key < node->key)
            node->left = insert(node->left, key, value);
        else
            node->right = insert(node->right, key, value);

        return node;
    }

    //以node为根的二叉搜索树中是否包含键值为key的结点;
    bool contain(Node* node, Key key){
        if(node == NULL)
            return false;

        if(key == node->key)
            return true;
        else if(key < node->key)
            return contain(node->left, key);
        else
            return contain(node->right, key);
    }

    //以node为根的二叉搜索树中,查找key所对应的value
    Value* search(Node* node, Key key){
        if(node == NULL)
            return NULL;

        if(key == node->key)
            return &(node->value);
        else if(key < node->key)
            return search(node->left, key);
        else
            return search(node->right, key);
    }

    //前序遍历
    void preOrder(Node* node){
        if(node != NULL){
            cout << node->key << endl;
            preOrder(node->left);
            preOrder(node->right);
        }
    }

    //中序遍历
    void inOrder(Node* node){
        if(node != NULL){
            inOrder(node->left);
            cout << node->key << endl;
            inOrder(node->right);
        }
    }

    //后序遍历
    void postOrder(Node* node){
        if(node != NULL){
            postOrder(node->left);
            postOrder(node->right);
            cout << node->key << endl;
        }
    }

    void destory(Node *node){
        if(node != NULL){
            destory(node->left);
            destory(node->right);

            delete node;
            count--;
        }
    }

    Node* minimum(Node* node){
        if(node->left == NULL)
            return node;
        return minimum(node->left);
    }

    Node* maximum(Node* node){
        if(node->right == NULL)
            return node;
        return maximum(node->right);
    }

    Node* removeMin(Node* node){
        if(node->left == NULL){
            Node* rightNode = node->right;
            delete node;
            count--;

            return rightNode;
        }

        node->left = removeMin(node->left);
        return node;
    }

    Node* removeMax(Node* node){
        if(node->right == NULL){
            Node* leftNode = node->left;
            delete node;
            count--;

            return leftNode;
        }

        node->right = removeMax(node->left);
        return node;
    }

    Node* remove(Node *node, Key key){
        if(node == NULL)
            return NULL;

        if(key < node->key){
            node->left = remove(node->left, key);
            return node;
        }else if(key > node->key){
            node->right = remove(node->right, key);
            return node;
        }else{
            //key == node->key
            if(node->left == NULL){ //(1)左孩子为空;
                Node *rightNode = node->right;
                delete node;
                count--;

                return rightNode;
            }

            if(node->right == NULL){ //(2)右孩子为空;
                Node *leftNode = node->left;
                delete node;
                count--;

                return leftNode;
            }

            //(3)左、右孩子都不为空的情况;
            Node *successor = new Node(minimum(node->right));
            count++;

            successor->right = removeMin(node->right);
            successor->left = node->left;
            delete node;
            count--;

            return successor;
        }
    }

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

    ~BST(){
        // TODO: 析构函数
        destory(root);
    }

    //返回树的大小;
    int size(){
        return count;
    }

    //判断树是否为空;
    bool isEmpty(){
        return count == 0;
    }

    //插入一个新的结点;
    void insert(Key key, Value value){
        root = insert(root, key, value);
    }

    //是否包含key
    bool contain(Key key){
        return contain(root, key);
    }

    //查找元素
    Value* search(Key key){
        return search(root, key);
    }

    //前序遍历
    void preOrder(){
        preOrder(root);
    }

    //中序遍历
    void inOrder(){
        inOrder(root);
    }

    //后序遍历
    void postOrder(){
        postOrder(root);
    }

    //层序遍历
    void levelOrder(){
        queue<Node*> q;
        q.push(root);

        while(!q.empty()){
            Node *node = q.front();
            q.pop();

            cout << node->key << endl;

            if(node->left)
                q.push(node->left);
            if(node->right)
                q.push(node->right);
        }
    }

    //最小值
    Key minimum(){
        assert(count != 0);
        Node *minNode = minimum(root);
        return minNode->key;
    }

    //最大值
    Key maximum(){
        assert(count != 0);
        Node *maxNode = maximum(root);
        return maxNode->key;
    }

    //删除最小值
    void removeMin(){
        if(root) root = removeMin(root);
    }

    //删除最大值
    void removeMax(){
        if(root) root = removeMax(root);
    }

    //删除某一个元素
    void remove(Key key){
        root = remove(root, key);
    }
};

#endif //WORKSPACE_BINARY_SEARCH_TREE_H
  • main函数调用
/**
 * C++ 语言: 二叉搜索树
 */

#include <iostream>
#include <vector>
#include "binary_search_tree.h"

using namespace std;

int main(){

    vector<int> nums = {28,16,13,22,30,29,42};

    //创建二叉搜索树;
    BST<int, int> bst;
    for(int i = 0; i < nums.size(); i++){
        bst.insert(nums[i], nums[i]);
    }

    //先序遍历二叉搜索树;
    bst.preOrder();

    //最大,最小值;
    cout << "max value:" << bst.maximum() << endl;
    cout << "min value:" << bst.minimum() << endl;
    cout << "contain value:" << bst.contain(12) << endl;
    cout << "search value:" << *bst.search(29) << endl;

    //删除元素;
    bst.remove(30);
    bst.preOrder();

    return 0;
}

参考资料

相关文章

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

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

  • 数据结构-二叉搜索树

    数据结构-二叉搜索树(BST) 定义:二叉搜索树是一个节点类的二叉树数据结构,包含以下特点: -左子树仅包含比根节...

  • 二叉树

    参考文章 百度 数据结构中有很多树的结构,其中包括二叉树、二叉搜索树、2-3树、红黑树等等。本文中对数据结构中常见...

  • Day3--搜索树

    在二叉判定树以及二分搜索的基础上,基于二叉树的搜索树产生,该数据结构可以随时进行调整,可以保证高效的搜索效率。 内...

  • 【学习】数据结构和算法

    数据结构 线性表:数组 栈 队列 链表树:二叉树 二叉树遍历 二叉搜索树 B树 红黑树 堆图:图其他:哈希表...

  • Go:实现二叉搜索树(BST)

    二叉搜索树是一种支持快速查找、增加和删除元素的数据结构。二叉搜索树中的节点是有序的,因此支持快速查找。该数据结构由...

  • 如何在Java中实现二叉搜索树

    二叉搜索树或BST是一种流行的数据结构,用于保持元素的顺序。二叉搜索树是二叉树,其中左子节点的值小于或等于父节点,...

  • 二叉排序树

    注 关于二叉搜索树更为详细的解释请详看 《大话数据结构》第八章 查找 中二叉搜索树这一小节 二叉排序树(Binar...

  • 图解“红黑树”原理,一看就明白

    学过数据结构都知道二叉树的概念,而又有多种比较常见的二叉树类型,比如完全二叉树、满二叉树、二叉搜索树、均衡二叉树、...

  • 数据结构与算法之二叉搜索树(八)

    目录 二叉搜索树概念二叉搜索树的接口设计,包括增,删,改,查平衡二叉搜索树 一 二叉搜索树 二叉搜索树是二叉树的一...

网友评论

      本文标题:数据结构 - 二叉搜索树

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