二分搜索树

 

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 *root;
    int count;

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

    int size(){
        return count;
    }

    bool isEmpty(){
        return count == 0;
    }
};

 

插入新的节点:

public:
    void insert(Key key, Value value){
        root = insert(root, key, value);
    }

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    // key > node->key
            node->right = insert( node->right, key, value);

        return node;
    }
};

 

是否包含有键值为key的节点:

public:
 bool contain(Key key){
        return contain(root, key);
    }

private:
// 查看以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 // key > node->key
            return contain( node->right , key );
    }

 

查找:

public:
    Value* search(Key key){
        return search( root , key );
    }

private:
     // 在以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 // key > node->key
            return search( node->right, key );
    }

 

前序遍历:

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

private:
    // 对以node为根的二叉搜索树进行前序遍历
    void preOrder(Node* node){

        if( node != NULL ){
            cout<<node->key<<endl;
            preOrder(node->left);
            preOrder(node->right);
        }
    }

中序遍历:

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

private:
    // 对以node为根的二叉搜索树进行中序遍历
    void inOrder(Node* node){

        if( node != NULL ){
            inOrder(node->left);
            cout<<node->key<<endl;
            inOrder(node->right);
        }
    }

后序遍历:

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

private:
     // 对以node为根的二叉搜索树进行后序遍历
    void postOrder(Node* node){

        if( node != NULL ){
            postOrder(node->left);
            postOrder(node->right);
            cout<<node->key<<endl;
        }
    }

 

析构函数:

public:
    ~BST(){
        destroy( root );
    }

private:
    void destroy(Node* node){

        if( node != NULL ){
            destroy( node->left );
            destroy( node->right );

            delete node;
            count --;
        }
    }

层序遍历:

public:
     // 层序遍历
    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 );
        }
    }

 

最小键值:

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

private:
    // 在以node为根的二叉搜索树中,返回最小键值的节点
    Node* minimum(Node* node){
        if( node->left == NULL )
            return node;

        return minimum(node->left);
    }

最大键值:

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

private:
     // 在以node为根的二叉搜索树中,返回最大键值的节点
    Node* maximum(Node* node){
        if( node->right == NULL )
            return node;

        return maximum(node->right);
    }

删除最小节点:

public:
     // 从二叉树中删除最小值所在节点
    void removeMin(){
        if( root )
            root = removeMin( root );
    }
private:
    // 删除掉以node为根的二分搜索树中的最小节点
    // 返回删除节点后新的二分搜索树的根
    Node* removeMin(Node* node){

        if( node->left == NULL ){

            Node* rightNode = node->right;
            delete node;
            count --;
            return rightNode;
        }

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

删除最大节点:

public:
     // 从二叉树中删除最大值所在节点
    void removeMax(){
        if( root )
            root = removeMax( root );
    }

private:
    // 删除掉以node为根的二分搜索树中的最大节点
    // 返回删除节点后新的二分搜索树的根
    Node* removeMax(Node* node){

        if( node->right == NULL ){

            Node* leftNode = node->left;
            delete node;
            count --;
            return leftNode;
        }

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

删除任意节点:

public:
    Node(Node *node){
            this->key = node->key;
            this->value = node->value;
            this->left = node->left;
            this->right = node->right;
        }
public:
    // 从二叉树中删除键值为key的节点
    void remove(Key key){
        root = remove(root, key);
    }

private:
    // 删除掉以node为根的二分搜索树中键值为key的节点
    // 返回删除节点后新的二分搜索树的根
    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 ){
                Node *rightNode = node->right;
                delete node;
                count --;
                return rightNode;
            }

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

            // node->left != NULL && node->right != NULL
            Node *successor = new Node(minimum(node->right));
            count ++;

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

            delete node;
            count --;

            return successor;
        }
    }

 

                      

原文地址:https://www.cnblogs.com/lzb0803/p/9193182.html

时间: 2024-11-02 10:57:46

二分搜索树的相关文章

并行二分搜索树bianry search tree

二分搜索树是一种设计良好的有序集合,在平衡的情况下,查找search,插入insertion,删除deletion都具有O(logn)的计算时间.本文讨论实现二分搜索树的具体细节. 二分搜索树的每个结点包含key域,以及至多两个孩子结点,并且左孩子小于当前结点的值,右孩子大于当前结点值.为了方便操作,每个结点还需要维护父结点的信息.从上面的描述可以看出,二分搜索树的任何一个子树同样也是二分搜索树. 搜索操作是所有操作的基础.搜索操作可以很容易用递归过程描述:key>cur.key,则搜索右子树:

[LeetCode] Closest Binary Search Tree Value II 最近的二分搜索树的值之二

Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target. Note: Given target value is a floating point. You may assume k is always valid, that is: k ≤ total nodes. You are guaranteed to have onl

二分搜索树的深度优先遍历和广度优先遍历

二分搜索树的特点 二分搜索树首先是一个二叉树,其次其必须满足的条件是:每个节点的键值必须大于其左子节点,每个节点的键值必须小于其右子节点,这样以左右孩子为根的子树仍为二分搜索树,需要注意的是,二分搜索树不一定是一颗完全二叉树. 深度优先遍历 深度优先遍历的基本思想:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.深度优先遍历的非递归的通用做法是采用栈.要特别注意的是,二分搜索树的深度优先遍历比较特殊,可以细分为前序遍历.中序遍历.后序遍历. 前序遍历:先访问当前节点,再依次

第二十六篇 玩转数据结构——二分搜索树

1.. 二叉树 跟链表一样,二叉树也是一种动态数据结构,即,不需要在创建时指定大小. 跟链表不同的是,二叉树中的每个节点,除了要存放元素e,它还有两个指向其它节点的引用,分别用Node left和Node right来表示. 类似的,如果每个节点中有3个指向其它节点的引用,就称其为"三叉树"... 二叉树具有唯一的根节点. 二叉树中每个节点最多指向其它的两个节点,我们称这两个节点为"左孩子"和"右孩子",即每个节点最多有两个孩子. 一个孩子都没有

《算法导论》动态规划—最优二分搜索树

案例 ?假如我们现在在设计一个英文翻译程序,要把英文翻译成汉语,显然我们需要知道每个单词对应的汉语意思.我们可以建立一颗二分搜索树来实现英语到汉语的关联.为了更快速地翻译,我们可以使用AVL树或者红黑树使每次查询的时间复杂度Θ(lgn),实际上对于字典翻译程序来说这么做存在一个问题,比如"the"这个单词经常用,却很有可能存在于十分远离树根的位置,而"machicolation"这种不常用的单词很可能存在于十分靠近树根的位置,这就导致查询频率高的单词需要的查询时间更

132.Find Mode in Binary Search Tree(二分搜索树的众数)

题目: Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST. 给定具有重复项的二叉搜索树(BST),找到给定BST中的所有众数(最频繁出现的元素). Assume a BST is defined as follows: 假设BST定义如下: The left subtree of a node

java——二分搜索树(递归、非递归)

~ import java.util.Stack; import java.util.LinkedList; import java.util.Queue; //二分搜索树 public class BST <E extends Comparable<E>> { private class Node{ public E e; public Node left, right; public Node(E e) { this.e = e; left = null; right = nu

十八 二分搜索树的三种遍历方式

三种遍历方式: package com.lt.datastructure.BST; public class BST<E extends Comparable<E>> { private class Node{ public E e; Node left,right; public Node(E e) { this.e = e; this.left = left; this.right = right; } } private Node root; private int size

十九 二分搜索树的广度优先遍历

二分搜索树广度优先遍历的实现: /* * 二分搜索树的层序遍历(广度优先遍历),队列实现 * 广度优先遍历优势在于更快找到想要查询的元素,主要用于搜索策略,算法设计--最短路径(无权图) */ public void levelOrder(){ Queue<Node> q = new LinkedList<>(); q.add(root); while(!q.isEmpty()){ Node cur = q.remove(); System.out.println(cur.e);